Skip to content

Add AGENT_VERSION_NOT_AVAILABLE error code #21

@nficano

Description

@nficano

ARCP v1.1 §12 adds three new error codes. PHP has LEASE_EXPIRED. Missing: BUDGET_EXHAUSTED (covered by cost.budget issue), AGENT_VERSION_NOT_AVAILABLE.

Add AGENT_VERSION_NOT_AVAILABLE to the error code enum and wire it into agent resolution. Document in errors guide.


Audit reference: ARCP SDK Audit v1.1 (2026-05-19)

Implementation prompt

Code is landed; this is a "verify + document + add tests" pass. PSR-4 root: Arcp\ -> src/. Tests: Arcp\Tests\ -> tests/. Spec ref: spec/docs/draft-arcp-1.1.md §12, §7.5.

Files to touch

  • src/Errors/ErrorCode.php — confirm AgentVersionNotAvailable = 'AGENT_VERSION_NOT_AVAILABLE' enum case. Confirm defaultRetryable() returns false for it (not in retryable set).
  • src/Errors/AgentVersionNotAvailableException.php — existing. Verify only.
  • src/Errors/ARCPException.php — confirm details() round-trips {agent, version}.
  • src/Errors/ErrorPayload.php — confirm fromException() reads code()->value and details() for this exception.
  • src/Runtime/ARCPRuntime.php — confirm setDefaultToolVersion() and resolveTool() throw AgentVersionNotAvailableException (already implemented, lines ~155 and ~179).
  • src/Internal/Runtime/ToolInvocationHandler.php — verify it surfaces an uncaught AgentVersionNotAvailableException as a wire error. If not, wrap resolveTool() in try/catch (see ticket Implement agent versioning name@version #18, step 4) and emit ToolError(ErrorPayload::fromException($e)).
  • src/Internal/Client/ErrorMapper.php — confirm agentVersionNotAvailable() constructs the exception with $err->details['agent'] and $err->details['version'].
  • docs/guides/errors.md — existing. Add an entry for AGENT_VERSION_NOT_AVAILABLE with the wire shape.
  • tests/Unit/Errors/AgentVersionNotAvailableExceptionTest.php (new) — focused unit.
  • tests/Integration/AgentVersionErrorTest.php (new) — wire-level integration.

Public API additions

Namespace Arcp\Errors:

enum ErrorCode: string {
    // ...
    case AgentVersionNotAvailable = 'AGENT_VERSION_NOT_AVAILABLE';
}

final class AgentVersionNotAvailableException extends ARCPException {
    public function __construct(
        string $agent,
        string $version,
        string $message = '',
        ?\Throwable $previous = null,
    );
    public function code(): ErrorCode;   // ErrorCode::AgentVersionNotAvailable
}

Step-by-step changes

  1. src/Errors/ErrorCode.php: open and confirm the enum case is present (line ~40) and defaultRetryable() does NOT include AgentVersionNotAvailable. The condition is a permanent failure for that version.
  2. src/Errors/AgentVersionNotAvailableException.php: confirm constructor accepts (string $agent, string $version, string $message = '', ?\Throwable $previous = null), sets details = ['agent' => $agent, 'version' => $version], retryable = false, and code() returns the enum case.
  3. src/Runtime/ARCPRuntime.php resolveTool(): confirm that when $ref->version !== null && !isset($bucket[$ref->version]) it throws new AgentVersionNotAvailableException($ref->name, $ref->version). Re-read line ~177-181.
  4. src/Internal/Runtime/ToolInvocationHandler.php handle(): wrap ($this->resolveTool)(AgentRef::parse($msg->tool)) so an AgentVersionNotAvailableException becomes a wire ToolError. Suggested patch:
try {
    $resolved = ($this->resolveTool)(AgentRef::parse($msg->tool));
} catch (AgentVersionNotAvailableException $e) {
    $this->runtime->emit($session, new ToolError(ErrorPayload::fromException($e)), [
        'correlation_id' => $env->id,
        'trace_id' => $env->traceId,
    ]);
    return;
}

Confirm ErrorPayload::fromException() already serializes details and retryable. If not, fix it (src/Errors/ErrorPayload.php).

  1. src/Internal/Client/ErrorMapper.php agentVersionNotAvailable(): confirm it reads $err->details['agent'] and $err->details['version'], falling back to '?' when missing or wrong type.
  2. docs/guides/errors.md: append a section under "v1.1 additions":
AGENT_VERSION_NOT_AVAILABLE
- Raised when: caller invokes `name@version` and `version` is not registered on the runtime.
- Wire details: `{agent: string, version: string}`.
- Typed exception: `Arcp\Errors\AgentVersionNotAvailableException`.
- Retryable: false (a different version must be requested).
  1. tests/Unit/Errors/AgentVersionNotAvailableExceptionTest.php (new):
    • testCodeEnum() — assert code()->value === 'AGENT_VERSION_NOT_AVAILABLE'.
    • testDetailsCarryAgentAndVersion() — instantiate, assert $e->details()['agent'] and $e->details()['version'] after construction.
    • testRetryableFalse().
    • testDefaultMessageFormat() — when $message === '', getMessage() reads "agent version not available: name@version".
  2. tests/Integration/AgentVersionErrorTest.php (new):
    • Spin up runtime + client (mirror tests/Integration/JobLifecycleTest.php).
    • Register planner@1.0.0. Call $client->invokeTool('planner@9.9.9').
    • Assert client raises AgentVersionNotAvailableException with $e->details()['agent'] === 'planner', version === '9.9.9', and that the underlying wire ToolError had code === 'AGENT_VERSION_NOT_AVAILABLE'.
  3. CONFORMANCE.md: add a row for AGENT_VERSION_NOT_AVAILABLE under v1.1 error codes (claim it once tests are green).

Tests to add

  • tests/Unit/Errors/AgentVersionNotAvailableExceptionTest.php (cases above).
  • tests/Integration/AgentVersionErrorTest.php:
    • testInvokeUnknownVersionRaisesTypedException()
    • testWireErrorPayloadShape() (snapshot the ToolError.error.details)

Verification commands

cd /Users/nficano/code/arpc/php-sdk
composer test -- --filter AgentVersion
composer stan
composer psalm

Acceptance

  • [task] ErrorCode::AgentVersionNotAvailable present with wire string AGENT_VERSION_NOT_AVAILABLE.
  • [task] AgentVersionNotAvailableException thrown by ARCPRuntime::resolveTool() and setDefaultToolVersion() on unknown version.
  • [task] ToolInvocationHandler::handle() translates the exception to a wire ToolError with details: {agent, version} (not an uncaught throw).
  • [task] ErrorMapper reconstructs the typed exception on the client.
  • [task] docs/guides/errors.md documents the code.
  • [task] CONFORMANCE.md claims AGENT_VERSION_NOT_AVAILABLE.
  • [task] Unit + integration tests added.
  • [task] composer stan && composer psalm && composer test all pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature implementationv1.1ARCP v1.1 feature work

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions