For AI agents: the complete documentation index is available at https://a3s-lab.github.io/Test/en/llms.txt, the full documentation bundle is available at https://a3s-lab.github.io/Test/en/llms-full.txt, and this page is available as Markdown at https://a3s-lab.github.io/Test/en/guide/troubleshooting.md.

Troubleshooting

A3S Test records specification admission, surface drivers, product assertions, session lifecycle, and repair state separately. Establish which boundary failed before changing business code. A red result proves that one boundary did not hold, but does not by itself prove a product defect.

Retain these five facts first

  1. The complete command and process exit code.
  2. The stable error code and message from JSON output.
  3. The current session or run identifier.
  4. The latest observation_id, page URL, and Test Kit revision.
  5. The smallest screenshot, accessibility tree, console, and page-error set that proves the problem.

Do not copy cookies, authorization headers, browser storage, production data, or provider credentials. Evidence may contain user input, so inspect redaction before sharing it.

Assign ownership by error scope

Error scopeWhat it normally meansInspect first
test.spec.*ACL, target, configuration, or artifact path failed admissionSuite fields, action type, target, origin, and relative path
test.driver.web.*Web adapter, browser protocol, origin, or lifecycle problemAdapter version, executable, page navigation, and startup log
test.driver.gui.*GUI profile, permission, window identity, or CUA sessionPlatform certification, app identity, accessibility permission, and exclusive worker
test.driver.tui.*PTY, ConPTY, or terminal semanticsCommand manifest, process tree, encoding, terminal size, and recording path
test.assert.*Current product state does not satisfy an explicit expectationActual page, stale expectation, match target, and assertion evidence
test.run.*Deadline, cancellation, scheduling, or cleanupTimeout, worker health, cancellation event, and owned cleanup
test.session.repair_*Finding, attempt, lease, or verification state problemRepair Ledger, request ID, attempt ID, and latest ready revision
Provider protocol errorIdentity, digest, budget, provenance, or response mismatchACL config, response schema, source or screenshot digest, and provider log

When JSON output contains both a root failure and a cleanup failure, retain both. A cleanup failure does not erase the product failure, and an assertion failure cannot hide incomplete cleanup.

The local Vibe Loop does not start

Run the static diagnosis before changing the application:

a3s-test doctor --json
a3s-test doctor --connect --json

Use the first command when no server is expected to be running. The unprobed URL is only a warning. Use --connect when validating an existing server. Apply the exact fix attached to each failed check; a missing Test Kit declaration, a declared but uninstalled package, and an incompatible installed version are separate failures.

If discovery selected the wrong script or port, regenerate deliberately:

a3s-test init --script dev:web --url http://127.0.0.1:4317 --force

Inspect .a3s-test/project.acl before running dev. The development command is an executable plus an argument list, not a shell expression. Keep custom environment preparation in the declared package script.

With a3s-test dev --json, parse stdout only as JSONL and send stderr to the developer log. A ready event with server: "existing" means A3S Test did not start and will not stop that server. server: "started" means the CLI owns the complete process tree. reason: "server_exit" identifies a server that stopped before Ctrl+C and includes its exit code when available.

Do not kill all Node or browser processes by name. Press Ctrl+C once and let bounded cleanup abort the exact browser session and owned server tree. A second interrupt is emergency cleanup. Unix also uses an EOF watchdog if the host is killed; Windows relies on a kill-on-close Job Object.

A session cannot start

Read the installed version and protocol first.

a3s-test --version
a3s-test agent schema
a3s-test capabilities --json

When agent schema succeeds but capabilities returns test.driver.web.version_unsupported, the CLI is operational and the selected Web adapter is outside its supported protocol range. Upgrade or select an adapter that matches this CLI. Do not bypass the version gate or treat adapter help output as a successful probe.

Declare a compatible standalone adapter and executable explicitly when needed.

A3S_TEST_AGENT_BROWSER="$(command -v agent-browser)" \
  a3s-test agent start http://127.0.0.1:3000 \
  --session smoke \
  --goal "Open the page" \
  --success "The main heading is visible" \
  --browser-driver standalone \
  --json

If startup still fails, check that the URL is listening, the adapter is executable, and headless-browser dependencies are installed. Never kill all Chrome or browser processes by name.

The observation is empty or the page is not ready

Inspect persisted state, then capture a complete observation.

a3s-test agent show --session smoke --json
a3s-test agent observe --session smoke --json

Check these facts in order.

  • The current URL still belongs to the session's exact-origin set.
  • The page is not parked on an authentication redirect, error page, or unapproved port.
  • The target is in the main document or a frame the driver can access.
  • The host page exposes native semantics or an ARIA name.
  • Test Kit page.ready and the relevant component ready values are true.

Bind waits to observable conditions.

{
  "type": "wait",
  "condition": {
    "type": "text",
    "value": "Order confirmation"
  }
}

Do not add infinite polling or an arbitrary long sleep. If the page never becomes ready, repair the host readiness signal or the success condition.

A hidden assertion or disappearance wait fails

Read the exact error before changing the locator.

ResultMeaningInspect next
Passed with visible = falseNo visible match existed at that observationAdd stability only if the state must remain hidden
test.assert.hiddenThe positive probe found a visible matchoutput.data.probe, target semantics, CSS, and transition state
test.assert.unstableThe target was initially hidden and became visible at a later sampleassertion.first, assertion.last, sample timing, and rollback
test.spec.hidden_target_unstableACL used ref() or visual_point()Replace observation-bound identity with a semantic or CSS target
test.driver.*The adapter could not establish visibilityTarget support, stale/ambiguous state, driver output, and logs
test.run.assertion_mode_invalidProgrammatic construction bypassed the ACL admission invariantConstruct hidden mode only around Assert(Visible(stable target))
test.run.wait_mode_invalidProgrammatic hidden wait used an invalid action, policy, or targetUse Wait(Visible(stable target)) without assertion stability
test.run.hidden_wait_probe_limitThe target stayed visible through all 1,201 bounded probesProduct transition, locator scope, and scenario-level readiness
test.run.timeout with wait dataThe target was still visible when the scenario deadline expiredlast_visible, preceding step time, and the declared deadline

expect hidden means “no visible match now.” Use wait hidden when the product transition itself must remove or hide the target. Its output.data.wait reports matched, timed_out, cancelled, probe_limit, or inconclusive, together with probe count and elapsed time. Use stable_for_ms only when the requirement is that the target remain hidden after the first successful hidden probe.

Do not replace a semantic locator with a snapshot ref. A missing ref can mean stale observation state, which is intentionally not accepted as proof that the product element is gone. Do not suppress test.driver.*; an invalid selector, ambiguous GUI match, malformed browser response, or lost surface leaves visibility unknown.

A stable expectation fails or times out

Start with the step error and do not tune the interval before assigning ownership.

ResultWhat it provesInspect next
Original test.assert.*The first sample was false, so no stability window startedTarget, product readiness, and the expectation itself
test.assert.unstableThe first sample passed and a later sample was falseFirst/last assertion data, sample count, visible flicker, hydration, or rollback
test.driver.*The driver could not complete a sampleAdapter log, command deadline, target support, and browser lifecycle
test.run.timeoutThe scenario deadline ended during the window or a sampleTotal scenario budget, preceding steps, driver latency, and retries
test.run.cancelledCancellation interrupted an interval or sampleThe cancellation source and cleanup result

For test.assert.unstable, read output.data.stability and compare observed_ms with required_ms. samples counts completed observation points. Step attempts counts every driver call and can be larger when infrastructure retries are enabled. assertion.last may be null when the failing driver command returned an error without data.

Calibrate in this order.

  1. Put a typed wait before the assertion if the test first needs to reach a ready state.
  2. Set stable_for_ms to the product-relevant settling period, not the longest time CI can tolerate.
  3. Set sample_interval_ms no larger than the shortest transient the test needs a reasonable chance to observe.
  4. Budget the scenario deadline for preceding work, the full window, command latency, and retry backoff.
  5. Prefer a semantic target that can be resolved on every render; do not carry a stale observation ref through DOM replacement.

Do not increase the interval merely to make a flicker disappear from samples. That reduces time resolution and can hide the defect. Do not add a sleep after the expectation; it creates no assertion evidence. Sampling remains discrete and cannot prove the state between observation points.

A ref is stale or the target is rejected

@eN and @cN are valid only in the latest observation that created them. Navigation, DOM changes, scrolling, viewport changes, focus, and browser-context switches can advance the revision. @eN, UI, screenshot, and coordinate evidence then expire. An @cN stable locator survives only when Test Kit 0.6.0 returns a complete revision delta that does not invalidate its private node ID; a changed or removed ID, reset_required, missing metadata, or an older Test Kit clears it.

a3s-test agent observe --session smoke --interactive --json
a3s-test agent click @e3 \
  --session smoke \
  --observation 8 \
  --json

Observe again and resolve the target again after a stale-ref error. If a custom integration receives delta.status = "reset_required", discard the old baseline and take a normal snapshot before continuing. Do not rewrite an old observation ID or move old coordinates into a CSS target.

@uN is permanently read-only. It can connect style, layout, or motion evidence but cannot target click, fill, drag, or an ACL action. Find a current @eN, a uniquely actionable @cN, or a stable semantic locator for the same node.

The page left an admitted origin

--allow-origin controls the exact scheme, host, and port that may be navigated and observed. --allow-domain permits network access to a hostname and does not expand action origins.

A3S Test stops issuing refs after the page moves to an unapproved origin. Confirm whether the redirect belongs to the test. Start a new session with an exact --allow-origin when it does. Retain origin-loss evidence and end the session when it does not.

Do not continue acting on an unknown page. http://127.0.0.1:3000 and http://localhost:3000 are different origins.

The Test Kit bridge is unavailable

Browser accessibility still works without a bridge, but component ownership, source hints, and @cN will be absent. Check these points in order.

  1. enabled is strictly true.
  2. The React app mounts A3STestKit on the client.
  3. The page did not mount only A3SReviewOverlay without the Context Runtime.
  4. The current frame is same-origin and accessible to the bridge.
  5. Hot reload did not leave multiple providers replacing each other.

Use a read-only bridge probe in the browser console.

import { getPageContextBridge } from '@a3s-lab/testkit';

const bridge = getPageContextBridge();
console.log({ handshake: bridge?.handshake(), pageContext: bridge?.probe() });

A production build with the overlay disabled is normal. CI can retain A3STestKit while omitting the visible review surface.

For the local review loop, run a3s-test dev --json. doctor proves only the static installed range; dev reports the exact live failure boundary. A missing required bridge produces test.driver.web.testkit_bridge_missing, an old runtime without handshake() produces test.driver.web.testkit_handshake_missing, and a compatible provider without the visible review host produces test.driver.web.testkit_review_overlay_missing. Follow the install or mount repair in that error instead of editing the project profile to suppress it.

Page Context is truncated

The response fields truncated, nextCursor, and ui.budget identify the budget that ran out. Respond in this order.

  1. Narrow the scope to a component, node, or region.
  2. Use summary or scoped detail for routine targeting.
  3. Reserve forensic detail for repair verification and design review.
  4. Read the next page with the returned opaque cursor.
  5. Confirm that the request does not try to increase installation ceilings.

The outer Page Context may remain valid when an incomplete UI graph is omitted. Mark the missing UI evidence as uncertain. Never fabricate layout nodes or edges to fill the gap.

Review Overlay does not appear

Check A3SReviewOverlay enabled, the outer provider, page <html lang>, and the Shadow DOM host. The overlay mounts only when a live bridge exists. Its default surface is one side panel with peer New feedback, Findings, and Preferences views; selecting a target replaces the marking tools with the editor in that same panel.

When keyboard tools do not respond, confirm that focus is outside text fields and editors. Letter shortcuts deliberately yield to editable controls. On mobile, check whether the host uses a full-screen layer with a z-index above the Test Kit panel.

A finding does not enter the repair queue

Separate draft state from submission. Saving a local draft, copying Markdown, and opening advice do not enter the Repair Ledger.

For a project started with a3s-test dev --json, do not run the command below in parallel. Confirm that ready.repair_bridge.state is watching, then read the repair_batch event from the existing dev stdout stream. The manual watch command is for a directly started agent session or an explicit bounded replay.

a3s-test agent repair-watch \
  --session smoke \
  --limit 20 \
  --timeout-ms 30000 \
  --json

Without repairEndpoint, the active browser session drains the bridge queue. With an endpoint, a failed same-origin POST does not delete the browser queue. Check protocol, content type, body limit, and route ownership, then retry from the same session.

Conflicting or overlapping findings may enter needs_input. Read the Repair Ledger and thread messages, ask a person to clarify, then requeue. Do not bypass the conflict by starting another workspace-mutating agent.

Editing finished but verification cannot pass

repair-complete ends only the editing phase. repair-verify still requires a newer ready page revision, a re-resolved target, success criteria, before-and-after browser-error baselines, and focused checks.

SymptomResponse
repair_verify_not_readyLet the app finish a new render, then run one bounded verification
Target cannot be foundCheck semantic locators, replacement target, and source hints without reusing private node IDs
Console or page errors increasedRepair the new errors and re-enter verification
Success criteria cannot be provenAdd an observable condition or let a person handle the unverifiable portion
Layout Mode proves only existenceAdd original-region, destination-region, or intersection evidence
ACL candidate fails admissionRepair syntax, origin, read-only actions, and assertions without writing the failed candidate into the product repository

A failed verification never auto-resolves. Explicit --auto-resolve-repairs still persists a passing review_ready event first.

A provider request fails

Visual grounding, design audit, and contract generation use separate protocols. Check provider and model identity, endpoint, authorization environment variable, deadline, cost, request bytes, candidate count, and response schema.

A3S Test rejects a response when a source file or screenshot changes during the request. Generate a fresh observation or draft instead of reusing an old digest. When the page revision changes after a provider returns geometry, observe and request again instead of converting those coordinates into a current click.

Cleanup did not complete

Stop dispatching actions, then finish or abort the exact session.

a3s-test agent abort --session smoke --json

The first Ctrl+C requests bounded cancellation and cleanup. A second signal terminates only process groups owned by the current run. A cleanup failure retains the session so the same caller can retry, while observation and action remain blocked.

Never run a global kill by browser or application name. It can close a user's existing sessions and remove the state A3S Test needs for terminal reporting and evidence.

Share a minimal diagnostic bundle

An inspectable bundle normally needs only these files.

command.txt
result.json
session.json
events.jsonl
report.json
artifacts/
├── screenshots/failure.png
├── evidence/accessibility.json
├── evidence/console.json
└── evidence/page-errors.json

Add HAR, trace, or video only when the failure concerns network or timing. Remove credentials, production data, and unrelated large artifacts before sharing.

Use the capability reference to inspect every entry point. Read the authority and safety model when the failure concerns model, human, browser, or source authority.