{"record":{"id":"4dd4371c92116b02","repo":"gastownhall/beads","slug":"lock-already-held-by-another-process-4dd437","errorCode":null,"errorMessage":"lock already held by another process","messagePattern":"lock already held by another process","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"internal/lockfile/lock_wasm.go","lineNumber":10,"sourceCode":"//go:build js && wasm\n\npackage lockfile\n\nimport (\n\t\"errors\"\n\t\"os\"\n)\n\nvar errProcessLocked = errors.New(\"lock already held by another process\")\n\nfunc flockExclusive(f *os.File) error {\n\t// WASM doesn't support file locking\n\t// In a WASM environment, we're typically single-process anyway\n\treturn nil // No-op in WASM\n}\n\n// FlockExclusiveNonBlocking attempts to acquire an exclusive lock without blocking.\n// In WASM, this is a no-op since we're single-process.\nfunc FlockExclusiveNonBlocking(f *os.File) error {\n\treturn nil\n}\n\n// FlockExclusiveBlocking acquires an exclusive blocking lock on the file.\n// In WASM, this is a no-op since we're single-process.\nfunc FlockExclusiveBlocking(f *os.File) error {\n\treturn nil\n}","sourceCodeStart":1,"sourceCodeEnd":28,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/lockfile/lock_wasm.go#L1-L28","documentation":"On WASM, errProcessLocked is declared for API parity with the other platforms, but flockExclusive is a no-op that always returns nil — WASM environments are typically single-process and file locking is unsupported. The sentinel can therefore only be matched, not normally produced, on this build target.","triggerScenarios":"Code paths referencing errProcessLocked/lockfile.IsLocked under GOOS=js/wasm compile and behave the same; in practice the lock functions succeed unconditionally, so this error is essentially unreachable on WASM unless surfaced by shared code that checks it.","commonSituations":"Cross-compiling bd to WASM (browser/Node) where unix and windows lock implementations are swapped out; tests built for WASM asserting lock behavior that does not apply on that platform.","solutions":["Do not rely on real mutual exclusion in WASM builds; use a JS-side or application-level lock if cross-process exclusion is required","Keep using lockfile.IsLocked/ErrLockBusy in shared code so behavior stays portable across platforms","Document that WASM locks are advisory no-ops to avoid false confidence in exclusivity"],"exampleFix":"// before\n// assumes Acquire excludes other processes on every platform\nerr := lockfile.Acquire(path)\n// after\nerr := lockfile.Acquire(path)\nif runtime.GOOS == \"js\" {\n    // locking is a no-op on WASM; enforce exclusion at the app level\n}","handlingStrategy":"fallback","validationCode":"if runtime.GOOS == \"js\" {\n    // lockfile is a no-op on wasm; use a JS-side mutex for cross-tab exclusion\n}","typeGuard":null,"tryCatchPattern":"err := lockfile.Acquire(path)\nif err != nil && lockfile.IsLocked(err) {\n    return fallbackApplicationLock() // wasm locks are advisory no-ops\n}","preventionTips":["Never assume real mutual exclusion from lockfile under GOOS=js","Enforce exclusivity with the host environment (JS mutex, single-threaded runtime) on wasm","Keep platform differences behind lockfile helpers instead of calling flock helpers directly"],"tags":["locking","wasm","portability","file-lock"],"backgroundTag":"lock-contention","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}