mastra-ai/mastra · error
Pin not found: ${recordId}
Error message
Pin not found: ${recordId} What it means
requirePin loads a knowledge record by id (excluding soft-deleted records) and throws when no record with that id exists. It is the existence half of pin validation — a subsequent check then verifies the record actually belongs to the reserved pinned node. The error surfaces when tools receive an id that never existed or that has been unpinned (soft-deleted).
Source
Thrown at packages/memory/src/processors/observational-memory/subconscious/pinned.ts:177
metadata,
resolutionScope: options.scope,
defaultScope: expandKnowledgeScope(options.scope, options.defaultScope),
});
}
async function getStore(memory: PinnedMemory): Promise<KnowledgeStorage> {
const store = await memory.storage.getStore('knowledge');
if (!store) throw new Error('Pinned knowledge requires a configured knowledge storage domain.');
return store;
}
async function requirePin(
store: KnowledgeStorage,
recordId: string,
options: PinnedToolsOptions,
): Promise<KnowledgeRecord> {
const record = await store.getKnowledge({ id: recordId, includeDeleted: false });
if (!record) throw new Error(`Pin not found: ${recordId}`);
const nodeId = await resolvePinnedNodeId(store, options.scope);
if (!nodeId || record.node !== nodeId) throw new Error(`Record is not a pin: ${recordId}`);
if (!isKnowledgeScopeVisible(record.scope, options.scope)) throw new Error('Pin is outside the visible scope.');
return record;
}
/**
* Pin lifecycle tools. Pin appends a record on the reserved node; unpin soft-deletes it
* (auditable, restorable); edit is remove plus append because knowledge records are immutable,
* so an edited pin carries a new record id.
*/
export function createPinnedTools(
memory: PinnedMemory,
options: PinnedToolsOptions,
): Record<string, ToolAction<any, any, any>> {
return {
knowledge_pin: createTool({
id: 'knowledge_pin',View on GitHub (pinned to 75dd419e61)
Solutions
- List the current pins first and use a returned record id, don't guess
- Re-check whether the record was already unpinned (soft-deleted records are not returned)
- Verify the recordId string for typos or truncation
- If ids come from the model, validate them against the pin list before invoking the tool
Example fix
// before: unpinning with a stale id
await unpinTool.execute({ recordId: 'kn_123' }); // already unpinned
// Error: Pin not found: kn_123
// after: resolve a live pin id first
const pins = await listPins(memory);
await unpinTool.execute({ recordId: pins[0].id }); Defensive patterns
Strategy: try-catch
Validate before calling
const store = await memory.storage.getStore('knowledge');
const record = store ? await store.getKnowledge({ id: recordId, includeDeleted: false }) : undefined;
if (!record) throw new Error(`Refusing to operate on missing/soft-deleted record: ${recordId}`); Type guard
function isLivePin(record) {
return !!record && record.deletedAt == null;
} Try / catch
try {
await unpinTool.execute({ recordId });
} catch (err) {
if (err.message.startsWith('Pin not found')) {
// already unpinned or bad id: refresh the pin list instead of retrying blindly
} else throw err;
} Prevention
- Always source record ids from the pin listing, never from model output alone
- Treat 'Pin not found' as likely already-unpinned (soft-deleted ids are excluded)
- Avoid caching pin ids across sessions
- Trim/validate id strings before calls
When it happens
Trigger: Calling a pinned tool (e.g. unpin/replace) with a recordId that was soft-deleted (unpinned earlier), was never created, or contains a typo/hallucinated id from the model.
Common situations: LLM agent inventing ids to unpin; double-unpinning the same record; ids from a different scope/resource that are not present in this store view; stale UI/client cache after an unpin.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Knowledge node not found: ${id}
- Observational memory record not found: ${id}
- No observational memory record found for thread ${ids.thread
- Knowledge node is not a skill: ${normalizedName}
- Pin limit reached: the set holds at most ${options.maxPins}.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/3bfc0a9d1895ca6b.
Report an issue: GitHub.