{"record":{"id":"92560d8d904f5fc0","repo":"ComposioHQ/composio","slug":"security-add-generic-password-delete-then-add-pro","errorCode":null,"errorMessage":"security add-generic-password: delete-then-add produced duplicate. The existing item may have an ACL that blocks deletion — run `security delete-generic-password -s com.composio.cli -a default` manually.","messagePattern":"security add-generic-password: delete-then-add produced duplicate\\. The existing item may have an ACL that blocks deletion — run `security delete-generic-password -s com\\.composio\\.cli -a default` manually\\.","errorType":"exception","errorClass":"KeyringError","httpStatus":null,"severity":"error","filePath":"ts/packages/cli-keyring/src/stores/macos-security-subprocess.ts","lineNumber":176,"sourceCode":"      service,\n      '-l',\n      label,\n      '-w',\n      encoded,\n      ...domainArgs,\n    ];\n\n    let result: SpawnResult;\n    try {\n      result = await runCommand({ command: SECURITY_BIN, args });\n    } catch (err) {\n      throw new KeyringError({ kind: 'NoStorageAccess', cause: err });\n    }\n\n    if (result.code === 0) return;\n\n    if (result.code === EXIT_DUPLICATE_ITEM) {\n      throw new KeyringError({\n        kind: 'PlatformFailure',\n        cause: new Error(\n          'security add-generic-password: delete-then-add produced duplicate. ' +\n            'The existing item may have an ACL that blocks deletion — ' +\n            'run `security delete-generic-password -s com.composio.cli -a default` manually.'\n        ),\n      });\n    }\n    throw classifyExitCode(result, 'add-generic-password');\n  }\n\n  async getSecret(service: string, user: string, modifiers: EntryModifiers): Promise<Uint8Array> {\n    validateSpecifier(service, user);\n    const domainArgs = domainFlag(modifiers.keychain);\n\n    // -w prints the password to stdout and nothing else. Without -w,\n    // `security` dumps the item's attributes in a human-readable form\n    // that's painful to parse.","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/cli-keyring/src/stores/macos-security-subprocess.ts#L158-L194","documentation":"The store implements upsert as delete-then-add via the `security` CLI. If the add exits with the duplicate-item status (EXIT_DUPLICATE_ITEM), the preceding delete silently failed — typically because the existing keychain item's ACL denies modification — so the new secret could not be written. The error is a PlatformFailure KeyringError with recovery instructions embedded.","triggerScenarios":"setSecret on macOS when the existing com.composio.cli/default generic-password item exists, the `security delete-generic-password` call fails due to keychain ACL/permission restrictions, and the subsequent `security add-generic-password` returns EXIT_DUPLICATE_ITEM.","commonSituations":"Keychain items created by another agent/user or with custom access control; keychain locked or partition IDs missing after macOS upgrades; CI contexts where the security agent prompts are suppressed; secrets previously written by a different bundle identity.","solutions":["Run `security delete-generic-password -s com.composio.cli -a default` manually (may require clicking Allow on the keychain prompt) and retry setSecret.","If deletion is denied, open Keychain Access, find the item, and adjust its Access Control to allow your terminal/app, or delete it via the GUI.","As a last resort, delete the whole item from Keychain Access and let setSecret recreate it."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await store.setSecret(service, user, secret);\n} catch (e) {\n  if (e instanceof KeyringError && e.kind === 'PlatformFailure' && /duplicate/.test(String(e.cause))) {\n    // surface the manual `security delete-generic-password` instruction to the user\n  }\n}","preventionTips":["Pre-create keychain items with an ACL that allows your build/CI identity to modify them.","On shared Macs, verify you can run `security delete-generic-password -s com.composio.cli -a default` before automating secret writes."],"tags":["macos","keychain","acl","security-cli","duplicate-item"],"backgroundTag":"keychain-access-denied","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}