本文へ移動
cccskills
無料GitHub で公開

local-cache-idempotency-fallback

Use database cache when external APIs aren't reliably idempotent. Use when: (1) External API claims idempotency but returns different values for same input, (2) Re-running a script creates duplicate resources, (3) Need stable identifiers across runs but external service generates new ones. Pattern: check database cache first, only call external API for genuinely new items, cache the result.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md4.1 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Local Cache as Idempotency Fallback

Problem

External APIs that should be idempotent (same input = same output) sometimes aren't. This causes problems when re-running scripts:

  • Duplicate resources created
  • Identifiers change between runs
  • State becomes inconsistent across systems

Context / Trigger Conditions

  • Re-running a script creates new resources instead of finding existing ones
  • External API "fixed" idempotency but still returns different values
  • Need stable identifiers (pubkeys, user IDs, resource IDs) across runs
  • Script works once but fails on subsequent runs due to changed IDs

Solution

Use database cache as the source of truth for idempotency:

// BEFORE: Always calls external API (brittle)
const { pubkey, token } = await externalApi.createUser(userId, username);
await db.saveUser({ userId, pubkey, token });

// AFTER: Check cache first (robust)
const cached = await db.getUser(userId);
let pubkey: string;
let token: string;

if (cached) {
  // Use cached values - stable across runs
  pubkey = cached.pubkey;
  token = cached.token;
  console.log(`Using cached pubkey: ${pubkey}`);
} else {
  // Only call external API for genuinely new items
  const result = await externalApi.createUser(userId, username);
  pubkey = result.pubkey;
  token = result.token;

  // Cache immediately for next run
  await db.saveUser({ userId, pubkey, token });
  console.log(`Created new pubkey: ${pubkey}`);
}

Key Pattern

  1. Check local first: Always query your database before calling external API
  2. Use cached values: If found, use local values even if stale
  3. Only create when missing: External API called only for genuinely new items
  4. Cache immediately: Save result right after successful API call
  5. Log the source: Indicate whether value is "(cached)" or "(new)" for debugging

Verification

  • Re-run script multiple times
  • Same identifier used each time (from cache)
  • No duplicate resources created in external system
  • Script is idempotent regardless of external API behavior

Example

Real-world application - Keycast account creation:

// Check if we have a cached account first (local DB is source of truth)
const cached = await db.getImportedUser(creator.user_id);
let pubkey: string;
let token: string;

if (cached) {
  // Use cached account - pubkey is stable
  pubkey = cached.pubkey;
  token = cached.token;
  console.log(`Pubkey: ${pubkey} (cached)`);
} else {
  // Create new account via external API
  const result = await keycast.createPreloadedUser(
    creator.user_id,
    username,
    displayName
  );
  pubkey = result.pubkey;
  token = result.token;
  console.log(`Pubkey: ${pubkey} (new)`);

  // Cache account in database immediately
  await db.saveImportedUser({
    vine_user_id: creator.user_id,
    username: creator.username,
    pubkey,
    token,
  });
}

Notes

  • This pattern works even when the external API claims to be idempotent
  • Database schema should use the input identifier as primary key (prevents duplicates)
  • Consider adding timestamps to track when cached values were created
  • For critical systems, add reconciliation logic to detect/fix drift
  • The cache becomes your source of truth - treat it accordingly

Related Patterns

  • Upsert on conflict: Use ON CONFLICT DO UPDATE to handle race conditions
  • Soft delete: Keep old records to track history of changes
  • Cache invalidation: Add TTL or manual refresh if external values can legitimately change

Related Skills

  • stale-cache-external-service-recovery: What to do when external service loses data and cached identifiers no longer exist (detect 404, delete cache, recreate)

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Fix ArgoCD ExternalSecret deployment failing with "namespace X is not permitted in project Y". Use when: (1) ExternalSecret shows OutOfSync in ArgoCD but won't sync, (2) ArgoCD application status shows "namespace X is not permitted in project 'infrastructure'", (3) ExternalSecret targets a namespace managed by a different ArgoCD project, (4) Using apps-of-apps pattern with separate infrastructure and application projects.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

Art direction for any content — reads text, PDF, Word, HTML, PPT, then proposes 2-3 creative directions with photography style, mood, and visual language. After selection, generates AI image prompts and visual briefs section-by-section. Use when the user shares content and needs visual direction, image sourcing, or creative direction for any material.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

Fix "Null check operator used on a null value" errors when an object is set to null during an async await. Use when: (1) Object reference is nullified while awaiting, (2) Code accesses object with ! after await returns, (3) Cancel/dispose operations run concurrently with async operations on same object. Solution: capture local reference before await.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

Add custom metadata headers (x-amz-meta-*) to AWS v4 signed requests for GCS S3-compatible API. Use when: (1) Adding custom metadata to GCS uploads via S3 API, (2) Getting signature mismatch errors after adding new headers, (3) x-amz-meta-* headers being ignored or causing 403 errors. Custom headers MUST be included in canonical headers and signed headers list.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

Fix password/secret authentication failures caused by trailing newlines when creating Google Cloud secrets (or similar) with bash here-strings. Use when: (1) Password authentication fails with correct password, (2) Secret created with `<<< "value"` syntax, (3) Error like "password authentication failed" or "invalid token" despite correct value. Bash here-strings (`<<<`) add a trailing newline that corrupts secrets.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

Fix silent video/media processing failures caused by URL extraction code that filters on file extensions (.mp4, .webm, .webp). Use when: (1) Media moderation, transcoding, or analysis silently skips files from Blossom or content-addressed storage servers, (2) URL extraction from Nostr event tags (imeta, r tags) drops URLs without recognized extensions, (3) CDN fallback URLs append .mp4 but the actual server uses extensionless content-addressed paths like /{sha256}. Common in Nostr video events (kind 34236) where different clients use different URL formats.

日本語の概要は準備中です。原文の説明を表示しています。

divinevideo/divine-mobile2662026年10月10日 更新

divinevideo のスキルをすべて見る

このスキルの問題を報告する