{"record":{"id":"7c521282a5472cdd","repo":"Hmbown/CodeWhale","slug":"unknown-recording-id-linux","errorCode":null,"errorMessage":"unknown recording \"${id}\"","messagePattern":"unknown recording \"(.+?)\"","errorType":"exception","errorClass":"ExecError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/backends/linux.mjs","lineNumber":773,"sourceCode":"        : [\"wl-copy\"];\n      need(cmd[0], \"clipboard write\");\n      spawnDetached(cmd[0], cmd.slice(1), String(text ?? \"\"), true);\n      return { written: String(text ?? \"\").length };\n    },\n    cursor_position: async () => {\n      await probeSession();\n      if (session === \"x11\") {\n        const out = await xdotool([\"getmouselocation\"]);\n        const m = /x:(-?\\d+)\\s+y:(-?\\d+)/.exec(out);\n        if (!m) throw new ExecError(`could not parse xdotool getmouselocation output: ${out}`);\n        return { x: Number(m[1]), y: Number(m[2]) };\n      }\n      throw new ExecError(\"cursor position needs an X11 session in this build\");\n    },\n    recordingStart: async () => {\n      throw Object.assign(new ExecError(\"Recording is unavailable on this platform until the recorder has session-owned cleanup. Use screenshots instead.\"), { code: \"owned_recording_unavailable\" });\n    },\n    recordingStop: async ({ id }) => { throw new ExecError(`unknown recording \"${id}\"`); },\n    recordingStatus: ({ id }) => ({ id, running: false }),\n    recordingList: async () => {\n      const dir = recordingsDir();\n      const out = fs.existsSync(dir)\n        ? fs.readdirSync(dir).filter((f) => /\\.(mp4|mkv|png)$/i.test(f)).map((f) => {\n            const st = fs.statSync(path.join(dir, f));\n            return { file: path.join(dir, f), bytes: st.size, modifiedAt: st.mtime.toISOString() };\n          }).sort((a, b) => b.modifiedAt.localeCompare(a.modifiedAt)).slice(0, 50)\n        : [];\n      return { dir, recordings: out, running: [] };\n    },\n  };\n\n  async function inputChain(x, y, act) {\n    await inputMove(x, y);\n    await act();\n    return { action_sent: true, at: { x: Number(x), y: Number(y) } };\n  }","sourceCodeStart":755,"sourceCodeEnd":791,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/backends/linux.mjs#L755-L791","documentation":"recordingStop on the Linux backend is a stub: recording is unavailable on this platform (see recordingStart, which always throws), so stopping any id throws `unknown recording \"<id>\"`. There is no recording registry, so no id can ever succeed.","triggerScenarios":"Calling recordingStop with any recording id on Linux; calling it after a recordingStart attempt that itself always failed.","commonSituations":"Portable agent code that unconditionally calls recordingStop in cleanup/finally paths regardless of platform; code ported from the macOS backend where recordings exist.","solutions":["Guard recordingStop behind a recordingList/recordingStatus check that the id actually exists","Skip recording lifecycle calls on Linux; use screenshot-based capture (the error in recordingStart recommends this)","Track recording handles in your own code and only call stop for handles you successfully started"],"exampleFix":"// before\nawait backend.recordingStop(id);\n// after\nconst recs = await backend.recordingList();\nif (recs.some(r => r.id === id)) await backend.recordingStop(id);","handlingStrategy":"validation","validationCode":"const list = await recordingList();\nif (!list.some(r => r.id === id)) return; // nothing to stop","typeGuard":null,"tryCatchPattern":"try { await recordingStop(id); } catch (e) { if (!/unknown recording/.test(e.message)) throw e; }","preventionTips":["Only call recordingStop for ids you successfully started","Check recording availability per-platform before using recording APIs at all","Make cleanup paths tolerant of unknown-id errors"],"tags":["recording","linux","resource-not-found","stub"],"backgroundTag":"resource-not-found","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}