Troubleshooting
Use this guide when playback behavior is failing in a real app and you need the next correct check, not a full API explanation.
Triage order
Section titled “Triage order”- Capture the exact
error.codefromplayback-errorwhen available. - Verify initialization order (
audioPlayer.setup()andmediaSession.setup()as needed). - Verify queue and active-track preconditions (
add(...),startIndex,getSnapshot()). - Verify runtime capabilities before sending optional commands (
getCapabilities()). - If symptoms look native-environment-specific, run
legato native doctor.
Error-code lookup
Section titled “Error-code lookup”Use error.code as the machine-stable branch key.
error.code | Most likely category | Next action |
|---|---|---|
player_not_setup | Initialization order | Ensure await audioPlayer.setup() ran before playback commands. See Set Up Legato Capacitor. |
empty_queue | Queue preconditions | Verify add({ tracks: [...] }) succeeds before play(). Then inspect getSnapshot().queue. |
invalid_index | Queue addressing | Validate skipTo({ index }), remove({ index }), or startIndex against current queue length. |
no_active_track | Active-track selection | Re-check startIndex and currentIndex in snapshot after queue insertion. |
unsupported_operation | Capability projection | Gate UI/action on getCapabilities().supported. See Capabilities. |
seek_failed | Seek runtime path | Confirm seek capability is currently supported before calling seekTo. |
invalid_url | Track input validity | Re-check Track.url value and transport-level accessibility in your environment. |
load_failed | Media loading | Re-check media URL reachability and track metadata assumptions; inspect error.details for adapter context. |
playback_failed | Runtime playback | Observe state transitions and error payload together (playback-state-changed + playback-error). |
platform_error | Native/platform layer | Collect error.details, then run legato native doctor for supported native checks. |
Symptom: play() does nothing or fails immediately
Section titled “Symptom: play() does nothing or fails immediately”- Run
await audioPlayer.getSnapshot()and confirm queue is not empty. - Confirm setup already completed in this app lifecycle (
await audioPlayer.setup()). - Confirm an active track exists (
currentIndex !== null,currentTrack !== null). - Register
onPlaybackErrorand branch byerror.code.
Symptom: seek controls are visible but seek fails
Section titled “Symptom: seek controls are visible but seek fails”- Read capabilities right before rendering/handling seek:
const caps = await audioPlayer.getCapabilities();const canSeek = caps.supported.includes('seek');- Hide or disable seek controls when
canSeekis false. - If
canSeekis true butseek_failedoccurs, logerror.detailsand runtime state snapshot for diagnosis.
Symptom: remote controls do not trigger app actions
Section titled “Symptom: remote controls do not trigger app actions”- Confirm
await mediaSession.setup()is called (separate fromaudioPlayer.setup()). - Confirm listeners are registered and retained (not garbage-collected by component teardown).
- Confirm you are testing on a device/context that emits media-session controls.
- For seek-specific remote controls, confirm
seekcapability is currently projected.
Symptom: local UI state drifts from actual playback state
Section titled “Symptom: local UI state drifts from actual playback state”- Prefer a sync controller (
createLegatoSyncorcreateAudioPlayerSync) for local projection. - Ensure
sync.start()is called once andsync.stop()runs on teardown. - On foreground resume, run
await sync.resync()before trusting stale UI state.
Symptom: native integration behaves differently than expected
Section titled “Symptom: native integration behaves differently than expected”- Run
legato native doctorfrom repository context supported by the CLI. - If you need a preview of safe changes, run
legato native configure --dry-run. - Apply changes intentionally with
legato native configure --applyand re-run doctor.
Diagnostic snippet (minimal)
Section titled “Diagnostic snippet (minimal)”import { audioPlayer, mediaSession, onPlaybackError, onPlaybackStateChanged,} from '@ddgutierrezc/legato-capacitor';
await audioPlayer.setup();await mediaSession.setup();
onPlaybackStateChanged(({ state }) => console.log('[state]', state));onPlaybackError(({ error }) => { console.error('[legato:error]', error.code, error.message, error.details);});
console.log('[snapshot]', await audioPlayer.getSnapshot());console.log('[capabilities]', await audioPlayer.getCapabilities());