Testing and release evidence

AudioRecord Dead-Object Diagnosis for Local AI

Trace recorder state, permission, route, format, lifecycle, interruption, release, recreation, and downstream transcription.

Review status: Fact and editorial QA complete; owner review pending · 2026-10-04 · Fact IDs: ANDROID-AUDIO-01, COVE-ASR-02

Direct answer

Treat AudioRecord.ERROR_DEAD_OBJECT as evidence that the reporting AudioRecord instance is no longer valid and needs recreation, not as a generic transcription-model failure. Android’s API reference notes a subtle boundary: if some data was successfully transferred, the dead-object code may be reported on the next read. Therefore, account for the bytes or frames already accepted before deciding whether the current segment is complete, incomplete, or uncertain. Do not blindly keep calling read() on the same invalid instance, and do not append a new recorder’s data to old partial bytes without checking session identity, format, and segment boundaries. The recovery path should have one recorder owner and a state machine. On the error, stop accepting new frames, preserve only segments already finalized by the pipeline, label the active segment according to the measured boundary, release the invalid recorder, and publish an interruption state. Before creating a replacement, verify that capture is still user-requested, permission and foreground requirements remain satisfied, the input route is understood, and the requested format is valid for the new instance. A successful constructor or initialized state does not prove the recorder is producing usable audio; run the next read and a controlled fixture before declaring capture resumed. For Cove, the official-source facts distinguish Android’s audio capture and format boundaries from the local transcription pipeline. The current Cove Voice pipeline processes PCM segments sequentially, merges non-empty results, and retains a visible placeholder for a segment that fails. That behavior can support user-visible recovery, but it does not mean every active recorder error is already handled or that every device route behaves alike. The app should associate each segment with a recording session ID and prevent callbacks from an old instance from writing into a new session after recreation. Test the precise failure boundary with a controlled recorder abstraction where possible. Inject a dead-object result before any data, after a partial read, at a segment boundary, while inference is processing an earlier segment, and during user cancellation. Record read result, bytes/frames accepted, active session ID, released state, partial segment disposition, UI state, and whether a new instance can be created. A test double can verify state transitions; device tests are still needed to characterize actual platform behavior. Do not claim support or failure rates from one injected unit-test path. Avoid automatic unbounded recreation. If recreation repeatedly fails, surface a classified capture error and give the user a stop, retry, or switch-input choice. Keep completed transcript text distinct from incomplete audio, and do not fabricate missing words. Diagnostic records should carry stage/error codes and format metadata, not raw audio or transcript content. Report only what was observed for the exact app, OS, route, and recorder configuration; a dead-object recovery protocol is a reliability method, not a promise that audio can always continue without interruption.

A microphone read returns a dead-object error mid-note

An offline voice note has several completed PCM segments and one active segment. AudioRecord.read() returns ERROR_DEAD_OBJECT after a partial read, while an earlier segment may still be transcribing. The app must recover without reusing the invalid recorder or mixing sessions.

Decision

Freeze the old session, account for transferred data, preserve finalized segments, release the invalid recorder, and create a new session only after rechecking user intent and capture conditions.

Expected outcome

The user sees an explicit interruption and can resume or finish; old callbacks cannot append data to the replacement session.

Evidence to collect

The claim becomes reviewable only when the following evidence is attached to the same artifact and test run:

  • Recorder and route state timeline
  • Known audio fixture
  • Failure, recreate, and retry outcome

A release claim is valid only for the recorded configuration and acceptance set. Generalization requires additional records.

Implementation workflow

  1. Classify the return value at the capture boundary. Treat ERROR_DEAD_OBJECT separately from zero bytes, a short successful read, ERROR_BAD_VALUE, permission loss, and downstream inference errors. Record whether data was transferred on the previous read before the error surfaced.
  2. Freeze and close the old recording session. Stop accepting frames from the invalid instance, mark its session ID closed, and release recorder resources exactly once. Ignore or classify late callbacks from that session so they cannot mutate a replacement session’s buffers.
  3. Resolve the active segment honestly. Finalize only data that meets the pipeline’s segment contract. If the segment is partial or its boundary is uncertain, mark it incomplete or preserve a visible placeholder; do not append replacement-session bytes to it as if capture were continuous.
  4. Recheck capture preconditions and recreate. Confirm the user still wants recording, permission and service conditions remain valid, select or verify the intended input route, and recreate AudioRecord with the documented format. Check initialization and perform a controlled read before setting the new session to capturing.
  5. Bound retries and verify end-to-end recovery. Test recreation success, repeated failure, cancellation, and in-flight transcription. Limit automatic attempts; after the policy is exhausted, present a clear retry/stop/input choice. Record completed transcript segments and the interruption without logging raw audio.

Keep each transition observable. A failure should identify the stage, artifact, runtime, and recovery action without logging private user content.

Acceptance criteria

  • ERROR_DEAD_OBJECT is classified as an invalid recorder instance, separately from model, permission, format, and ordinary empty-read failures.
  • Transferred data and active-segment status are accounted for before releasing the old recorder; no session bytes are silently mixed.
  • The invalid recorder is released and late callbacks are prevented from mutating the replacement session.
  • Recreation is bounded, user intent and capture conditions are rechecked, and the UI exposes interruption and recovery choices.

Decision table

DimensionChoice or evidenceHow to interpret it
Retry read on same objectDo not reuse after ERROR_DEAD_OBJECTThe API identifies the object as invalid and requiring recreation.
Recreate with prior settingsRecheck route, permission, format, and session identity firstMay restore capture when conditions allow; constructor success alone is not proof of good audio.
Restart the entire noteUse only if the product explicitly chooses this recoverySimpler state but can discard finalized segments; explain and preserve known-complete text where possible.

Failure patterns to prevent

  • Reusing a failed recorder blindly
  • Blaming the speech model before capture

Also prevent silent fallback, unpinned artifacts, missing cancellation, and conclusions that combine unlike configurations. Store unsuccessful runs alongside successful ones.

Minimum reproducibility record

LayerRecord
DeviceManufacturer, model, chipset, RAM class, operating-system build
SoftwareApplication version and git commit
ModelFamily, variant, revision, format, file length, hash, quantization
RuntimeName, revision, requested backend, observed backend evidence
WorkloadFixture revision, input hash, prompt hash, output policy
OutcomeCompleted, failed, cancelled, fallback, and privacy-safe diagnostics

Release checklist

  • ☐ The primary query is answered without an unsupported number.
  • ☐ Every artifact and runtime is pinned.
  • ☐ The representative task and failure policy are explicit.
  • ☐ Lifecycle, cancellation, cleanup, and fallback are tested.
  • ☐ User-content and network boundaries are documented.
  • ☐ Result wording applies only to the recorded configuration.
  • ☐ The page links to raw method or evidence when results are added.

Sources and related evidence

Chinese deployment and troubleshooting content is organized in the .奇连 AI 端侧专题.

Frequently asked questions

Does ERROR_DEAD_OBJECT mean the model crashed?

No. It is an AudioRecord capture-object error indicating that the instance is no longer valid and should be recreated. Keep capture failure separate from transcription or inference failure.

Can the current read return valid audio before the error?

Yes. Android documents that when data was successfully transferred, the dead-object code may arrive on the next read. Track accepted bytes/frames and apply the segment contract before deciding what to keep.

Should the app automatically recreate AudioRecord forever?

No. Repeated failures need a bounded policy and a visible user choice. Recheck permission, route, and capture state; if recreation does not recover, let the user stop or choose another input rather than looping silently.