> ## Documentation Index
> Fetch the complete documentation index at: https://facturas-sdk.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Handling and Troubleshooting in facturas

> All facturas errors extend ArcaError with a stable code string. Learn the error hierarchy, predicate helpers, and how to diagnose common issues.

Every error thrown by the `facturas` SDK extends `ArcaError` and exposes a stable `code` string that you can match in your error-handling logic without parsing message text. The code never changes between patch releases, so you can safely store it in logs, route on it in monitoring rules, and use it in tests.

## Error class hierarchy

| Class                     | `code`                      | When thrown                                                                                                |
| ------------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `ArcaConfigurationError`  | `ARCA_CONFIGURATION_ERROR`  | Client configuration is missing or invalid (e.g. no `ARCA_ENVIRONMENT`, unrecognisable CUIT)               |
| `ArcaInputError`          | `ARCA_INPUT_*`              | Your issuance input is invalid (e.g. malformed date, amount precision violation, idempotency key mismatch) |
| `ArcaAuthenticationError` | `ARCA_AUTHENTICATION_ERROR` | WSAA authentication was explicitly rejected by ARCA                                                        |
| `ArcaTransportError`      | `ARCA_TRANSPORT_ERROR`      | HTTP or network failure (connection error, timeout, non-XML error response)                                |
| `ArcaSoapFaultError`      | `ARCA_SOAP_FAULT`           | ARCA returned a SOAP `<Fault>` element                                                                     |
| `ArcaServiceError`        | `ARCA_SERVICE_ERROR`        | ARCA rejected the operation at the business level (e.g. WSFE error codes)                                  |

All classes are importable from `facturas` or from the dedicated `facturas/errors` subpath.

## Predicate helpers

When you cannot use `instanceof` — for example across module boundaries or in frameworks that re-wrap errors — use the exported predicate functions:

```typescript theme={null}
import { isArcaAuthenticationError } from "facturas/errors";

if (isArcaAuthenticationError(error)) {
  // error is narrowed to ArcaAuthenticationError
}
```

The SDK exports `isArcaAuthenticationError` as the only predicate helper. For all other error classes — `ArcaConfigurationError`, `ArcaInputError`, `ArcaTransportError`, `ArcaSoapFaultError`, `ArcaServiceError` — use `instanceof` directly.

## Handling errors in practice

```typescript theme={null}
import {
  ArcaAuthenticationError,
  ArcaConfigurationError,
  ArcaInputError,
  ArcaServiceError,
  ArcaSoapFaultError,
  ArcaTransportError,
} from "facturas/errors";

try {
  const result = await arca.issue(input);
} catch (e) {
  if (e instanceof ArcaAuthenticationError) {
    // reason: "invalid_token" | "unauthorized_computer" |
    //         "missing_relationship" | "authentication_rejected"
    console.error("Auth failed:", e.reason, e.service, e.operation);
    if (e.providerCode !== undefined) {
      console.error("Provider code:", e.providerCode);
    }
  } else if (e instanceof ArcaInputError) {
    console.error("Input error:", e.code, e.field, e.expected);
  } else if (e instanceof ArcaServiceError) {
    console.error("ARCA rejected:", e.serviceCode, e.message);
  } else if (e instanceof ArcaSoapFaultError) {
    console.error("SOAP fault:", e.faultCode, e.message);
  } else if (e instanceof ArcaTransportError) {
    console.error("Network error:", e.code, "HTTP status:", e.statusCode);
  } else if (e instanceof ArcaConfigurationError) {
    console.error("Bad config:", e.message);
  } else {
    throw e;
  }
}
```

## `ArcaAuthenticationError` fields

`ArcaAuthenticationError` exposes a narrow, safe set of diagnostic fields. Raw WSAA response bodies and credential values are never attached.

<ResponseField name="reason" type="&#x22;invalid_token&#x22; | &#x22;unauthorized_computer&#x22; | &#x22;missing_relationship&#x22; | &#x22;authentication_rejected&#x22;">
  Stable typed reason for the authentication failure.
</ResponseField>

<ResponseField name="service" type="string">
  The ARCA service that rejected authentication (e.g. `"wsfe"`, `"wsmtxca"`).
</ResponseField>

<ResponseField name="operation" type="string">
  The specific operation that triggered the error.
</ResponseField>

<ResponseField name="providerCode" type="string | number | undefined">
  The provider-supplied error code, if available. Redacted to 512 characters maximum.
</ResponseField>

## `ArcaInputError` codes

`ArcaInputError` carries one of these stable `code` values, along with optional `field` and `expected` properties pointing to the offending input:

| Code                               | Meaning                                                                                                  |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `ARCA_INPUT_IDEMPOTENCY_MISMATCH`  | A different input, operation, provider, or explicit number was submitted for an existing idempotency key |
| `ARCA_INPUT_INVALID_DATE`          | A date field is malformed or out of range                                                                |
| `ARCA_INPUT_INVALID_AMOUNT`        | An amount field contains a non-integer or unexpected type                                                |
| `ARCA_INPUT_AMOUNT_PRECISION`      | An amount exceeds the allowed decimal precision                                                          |
| `ARCA_INPUT_AMOUNT_MISMATCH`       | Totals in the input do not reconcile                                                                     |
| `ARCA_INPUT_INVALID_EXCHANGE_RATE` | The exchange rate value is invalid                                                                       |
| `ARCA_INPUT_INVALID_VALUE`         | A field value is outside the allowed set                                                                 |
| `ARCA_INPUT_MISSING_FIELD`         | A required field is absent                                                                               |
| `ARCA_INPUT_RESERVED_FIELD`        | A field that the SDK manages internally was supplied by the caller                                       |

## Troubleshooting FAQ

<Accordion title="coe.alreadyAuthenticated — WSAA rejects the login attempt">
  ARCA's WSAA rejects a login request when a valid ticket for the same certificate and service is already active. This happens when multiple workers or serverless invocations each attempt a cold-start token fetch simultaneously.

  **Fix:** configure a shared `wsaaSessionStore` (or a unified `store`) so that workers reuse valid tickets instead of each fetching a new one. The in-memory cache cannot be shared across process boundaries. See [Stores](/guides/stores) for adapter options and [Configuration](/guides/configuration#wsaa-session-caching) for the `wsaaSessionStore` interface.
</Accordion>

<Accordion title="ARCA_INPUT_IDEMPOTENCY_MISMATCH — the idempotency key already exists with different input">
  You submitted an idempotency key that is already recorded in the store, but the new input differs from the original — the operation, provider (`wsfe` vs `wsmtxca`), explicit voucher number, or input payload changed.

  **Fix:** Either resubmit with the exact original input to retrieve the existing outcome, or generate a new idempotency key for the changed request. Idempotency reservation records are immutable and cannot be overwritten.
</Accordion>

<Accordion title="ARCA_CONFIGURATION_ERROR on startup — missing environment variable">
  `createArcaClient()` validates configuration immediately and throws if any required field is absent. The most common cause is a missing `ARCA_ENVIRONMENT`.

  **Fix:** Verify that all four required environment variables are set in your deployment environment:

  * `ARCA_TAX_ID` — 11-digit CUIT
  * `ARCA_CERTIFICATE_PEM` — PEM-encoded certificate
  * `ARCA_PRIVATE_KEY_PEM` — PEM-encoded private key matching the certificate
  * `ARCA_ENVIRONMENT` — exactly `test` or `production`

  Run `npx facturas check` to diagnose configuration problems from the command line. See [CLI Commands](/cli/commands) for details.
</Accordion>

<Accordion title="Network errors or timeouts — requests to ARCA are failing">
  `ArcaTransportError` is thrown when the HTTP connection fails, times out, or returns a non-XML error response. ARCA's services can occasionally be slow or unavailable, especially during peak hours.

  **Fix:** Increase the `timeout` option and configure `retries` with a `retryDelay` in your client:

  ```typescript theme={null}
  const arca = createArcaClient({
    timeout: 60_000,   // 60 seconds
    retries: 3,
    retryDelay: 1_000, // 1 second between attempts
  });
  ```

  Transport retries apply only to `ArcaTransportError`. SOAP faults and business rejections are not retried. Authorization calls (`issue()`, `issueCreditNote()`) always make exactly one CAE request per invocation regardless of the `retries` setting.
</Accordion>

<Accordion title="Expired or mismatched certificate">
  If your certificate PEM is expired, ARCA will reject WSAA authentication. If the certificate and private key do not correspond to each other, the SDK will fail to sign the WSAA request.

  **Fix:** Replace the `ARCA_CERTIFICATE_PEM` value with a renewed certificate that was generated from the same private key. Redeploy or restart the process so the new value is picked up. Confirm the certificate and key match before deploying by verifying that their public key fingerprints are identical.
</Accordion>

<Accordion title="Service not authorised — valid certificate but ARCA rejects the service">
  Your certificate may be valid but not authorised for the target ARCA service or environment.

  **Fix:** In `test`, re-check your WSASS homologation setup and confirm the service relationship for your CUIT. In `production`, verify the service authorisation in ARCA's portal for each service (`wsfe`, `wsmtxca`, `ws_sr_padron_a4`, etc.) and confirm that `ARCA_ENVIRONMENT=production` is set.
</Accordion>

<Accordion title="WSFE error 10015 — invalid DocTipo / DocNro combination">
  ARCA error `10015` indicates that the receiver document type and number combination is inconsistent for the selected voucher type and total. Factura B has specific rules about when a CUIT, DNI, or final-consumer identification is required based on the invoice total.

  **Fix:** Check the receiver's `condition`, `cuit`, and the invoice total against ARCA's rules for the voucher type. For amounts above the final-consumer threshold, a full CUIT is required.
</Accordion>

<Accordion title="WSFE error 10016 — wrong voucher number">
  ARCA error `10016` means the number in `CbteDesde` is not the next valid number for that sales point and voucher type. This happens when another process has issued a voucher between your `getNextVoucherNumber()` call and your `issue()` call.

  **Fix:** Call `getNextVoucherNumber()` immediately before authorizing — not cached from an earlier call — to get the current next number. When using `idempotencyKey`, the SDK handles number assignment for you; only specify an explicit `number` when you have a strong reason to do so.
</Accordion>

## Diagnostic checklist

When an error is unclear, work through these steps in order:

1. Confirm the certificate and private key correspond to each other (matching public key fingerprint).
2. Confirm `ARCA_ENVIRONMENT` is set to the correct value for your deployment.
3. Confirm the service authorisation is in place for that environment.
4. Confirm the voucher type, document type, and amount combination is valid for the issuer and receiver conditions.
5. Confirm your process is not reusing a stale assumption about the next voucher number.

For command-line diagnostics, run `npx facturas check`. See [CLI Commands](/cli/commands) for the full list of available checks.
