mastra-ai/mastra · error · HTTPException

Failed to resolve updated prompt block

Error message

Failed to resolve updated prompt block

What it means

After a successful update, the handler re-reads the prompt block via getByIdResolved with status 'draft' to return the fully resolved (inherited/merged) configuration. If that read returns null even though the update succeeded, the server throws this 500, signalling an unexpected internal inconsistency rather than a client mistake.

Source

Thrown at packages/server/src/server/handlers/stored-prompt-blocks.ts:309

      const providedConfigFields = Object.fromEntries(Object.entries(configFields).filter(([_, v]) => v !== undefined));

      // Handle auto-versioning with retry logic for race conditions
      // This creates a new version if there are meaningful config changes.
      // It does NOT update activeVersionId — the version stays as a draft until explicitly published.
      await handleAutoVersioning(
        promptBlockStore as unknown as VersionedStoreInterface,
        storedPromptBlockId,
        'blockId',
        PROMPT_BLOCK_SNAPSHOT_CONFIG_FIELDS,
        existing,
        updatedPromptBlock,
        providedConfigFields,
      );

      // Return the resolved prompt block with the latest (draft) version so the UI sees its edits
      const resolved = await promptBlockStore.getByIdResolved(storedPromptBlockId, { status: 'draft' });
      if (!resolved) {
        throw new HTTPException(500, { message: 'Failed to resolve updated prompt block' });
      }

      const latestVersion = await promptBlockStore.getLatestVersion(storedPromptBlockId);
      const hasDraft = !!(
        latestVersion &&
        (!resolved.activeVersionId || latestVersion.id !== resolved.activeVersionId)
      );

      return { ...resolved, hasDraft };
    } catch (error) {
      return handleError(error, 'Error updating stored prompt block');
    }
  },
});

/**
 * DELETE /stored/prompt-blocks/:storedPromptBlockId - Delete a stored prompt block
 */

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Retry the request — a transient race usually resolves on the next call.
  2. Confirm the record still exists after the update (GET by id).
  3. Upgrade the storage adapter to a version with a correct getByIdResolved draft-status implementation.
  4. If using a custom store, ensure getByIdResolved honors { status: 'draft' } and returns the resolved record.
  5. File a bug with @mastra/core/server if a fresh, simple update reliably reproduces this.
Defensive patterns

Strategy: retry

Validate before calling

const check = await fetch(`/api/stored-prompt-blocks/${id}`).then(r => r.ok);
if (!check) throw new Error('Prompt block disappeared before update');

Type guard

function isResolvedBlock(v: unknown): v is { id: string; activeVersionId?: string | null } {
  return !!v && typeof v === 'object' && typeof (v as any).id === 'string';
}

Try / catch

async function updateWithRetry(id: string, body: unknown, tries = 3) {
  for (let i = 0; i < tries; i++) {
    const res = await fetch(`/api/stored-prompt-blocks/${id}`, { method: 'PATCH', body: JSON.stringify(body) });
    if (res.status === 500) continue; // transient resolution failure
    if (!res.ok) throw new Error(`Update failed: ${res.status}`);
    return res.json();
  }
  throw new Error('Failed to resolve updated prompt block after retries');
}

Prevention

When it happens

Trigger: An update request whose follow-up resolved read returns null — typically a race (the record was deleted between update and re-read), or a storage adapter whose getByIdResolved with { status: 'draft' } is buggy/unimplemented and returns null for a valid record.

Common situations: Concurrent deletion of the same prompt block while an update is in flight; storage adapter version with an incomplete getByIdResolved/draft-resolution implementation; custom storage implementations that ignore the status option.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/8e1fd8f3fd81df56. Report an issue: GitHub.