paperclipai/paperclip · error
Teams private state could not be sealed
Error message
Teams private state could not be sealed
What it means
sealPrivate encrypts/MACs Teams private state (a purpose/value pair) through a prepared crypto context; any failure inside the try block is swallowed and rethrown as this opaque error, discarding the original cause. It is called when sealing Teams file-consent bindings, so binding persistence fails if private-state sealing fails.
Source
Thrown at server/src/services/chat-teams-file-consent.ts:118
async function sealPrivate(
context: TeamsFilePrivateContext,
purpose: string,
value: unknown,
): Promise<TeamsFileCiphertext> {
const parsed = privateContextSchema.safeParse(context);
if (!parsed.success) throw new Error("Invalid Teams private state");
try {
const prepared = await getSecretProvider("local_encrypted").createSecret({
value: JSON.stringify({
schema: "paperclip.teams.file-private.v1",
context: parsed.data,
purpose,
value,
}),
});
return prepared.material;
} catch {
throw new Error("Teams private state could not be sealed");
}
}
async function openPrivate(
context: TeamsFilePrivateContext,
purpose: string,
material: TeamsFileCiphertext,
): Promise<unknown> {
try {
const parsedContext = privateContextSchema.parse(context);
// Bound even corrupted database material before passing it to the provider.
if (Buffer.byteLength(JSON.stringify(material)) > 128 * 1024)
throw new Error();
const plaintext = await getSecretProvider("local_encrypted").resolveVersion(
{ material, externalRef: null },
);
if (Buffer.byteLength(plaintext) > 64 * 1024) throw new Error();
const envelope = zView on GitHub (pinned to 01ad858492)
Solutions
- Check that the Teams private-state key/secret is configured and present in the environment
- Temporarily log inside the catch (or wrap the inner call) to recover the original error — it is currently discarded
- Verify the crypto prepare context and purpose strings match what sealPrivate expects after any refactor
Example fix
// before
} catch {
throw new Error("Teams private state could not be sealed");
}
// after
} catch (error) {
throw new Error("Teams private state could not be sealed", { cause: error });
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!privateStateKey || privateStateKey.length < MIN_KEY_BYTES) throw new Error('Teams private state key missing/too short'); Try / catch
try { const material = sealTeamsFileConsentBinding(binding, ctx); } catch (err) { if ((err as Error).message === 'Teams private state could not be sealed') { alertSecretsMisconfigured(); return null; } throw err; } Prevention
- Provision and verify Teams sealing keys in every environment at startup
- Preserve error.cause when rethrowing (fix the catch clause) so failures are diagnosable
- Smoke-test seal/open round-trip after key rotation or refactors
When it happens
Trigger: Key material missing or malformed (unavailable secrets store, wrong key length), the prepare/seal primitive throwing (bad algorithm config, corrupt context), or environment crypto failures during createTeamsFileConsentBinding/seal flows.
Common situations: Missing or rotated encryption keys in a new environment; NODE_ENV/config change pointing at an empty secrets store; platform without required crypto support; a refactor changed the private-context shape expected by the sealer.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Teams destination is missing its verified service URL
- Teams destination contains an invalid service URL
- Teams destination contains an untrusted service URL
- decodeThreadId is unavailable
- openDM is unavailable
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/62b878330db6e9bb.
Report an issue: GitHub.