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

nostr-addressable-event-d-tag-requirement

Fix duplicate Nostr events (Kind 30000+ parameterized replaceable events) caused by missing d-tag. Use when: (1) Same content appears multiple times on relay for same pubkey, (2) Events aren't being replaced/updated as expected, (3) Publishing NIP-71 video events (Kind 34236) or other addressable events and seeing duplicates. The d-tag is REQUIRED for addressability - without it, each publish creates a new non-replaceable event.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md4.4 KB

SKILL.md(原文)

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

Nostr Addressable Event d-tag Requirement

Problem

When publishing parameterized replaceable events (Kind 30000-39999, including NIP-71 video events Kind 34236), events appear as duplicates on the relay instead of replacing each other. The same content shows up multiple times for the same user.

Context / Trigger Conditions

  • Publishing Kind 30000+ events (parameterized replaceable events)
  • Same video/content appears multiple times in user's feed
  • Events have identical pubkey, kind, and content but different event IDs
  • Relay returns multiple events when you expect one
  • Using NIP-71 (Kind 34236) for video events
  • Using NIP-23 (Kind 30023) for long-form content
  • Any addressable event type showing duplicates

Solution

Root Cause

Parameterized replaceable events (Kind 30000-39999) require a d tag to be addressable. The combination of pubkey + kind + d-tag value forms the unique address. Without a d tag, the relay treats each event as a separate non-replaceable event.

Fix

Always include a d tag with a unique identifier for the content:

// CORRECT - has d tag, will be replaceable
const event = {
  kind: 34236, // NIP-71 video
  pubkey: userPubkey,
  content: "Video description",
  tags: [
    ["d", videoId],  // REQUIRED for addressability
    ["title", "My Video"],
    ["url", "https://..."],
    // ... other tags
  ]
};

// WRONG - missing d tag, creates new event each time
const badEvent = {
  kind: 34236,
  pubkey: userPubkey,
  content: "Video description",
  tags: [
    ["title", "My Video"],  // No d tag!
    ["url", "https://..."],
  ]
};

For NIP-71 Video Events

Use the video's unique identifier (vine_id, video_id, etc.) as the d-tag value:

tags.push(["d", video.id]);

Cleaning Up Existing Duplicates

  1. Fetch all events for the pubkey: { kinds: [34236], authors: [pubkey] }
  2. Identify events without d-tags (these are the duplicates)
  3. Publish NIP-09 deletion events (Kind 5) referencing the bad event IDs
  4. Republish with proper d-tags

Verification

After adding the d-tag:

  1. Publish the same content twice
  2. Query the relay for events with that pubkey+kind
  3. Should return only ONE event (the latest)
  4. Event ID will change but d-tag address remains constant
// Verify no duplicates
const events = await ndk.fetchEvents({ kinds: [34236], authors: [pubkey] });
const byDTag = new Map();
for (const e of events) {
  const d = e.tags.find(t => t[0] === 'd')?.[1];
  if (!byDTag.has(d)) byDTag.set(d, []);
  byDTag.get(d).push(e);
}
// Each d-tag value should have exactly 1 event
for (const [d, evts] of byDTag) {
  if (evts.length > 1) console.log(`Duplicate: d=${d} has ${evts.length} events`);
}

Example

Before fix - events without d-tag create duplicates:

Event 1: id=abc123, kind=34236, tags=[["title", "My Video"]]
Event 2: id=def456, kind=34236, tags=[["title", "My Video"]]  // Duplicate!

After fix - events with d-tag replace each other:

Event 1: id=abc123, kind=34236, tags=[["d", "video-001"], ["title", "My Video"]]
// Republishing same content...
Event 2: id=xyz789, kind=34236, tags=[["d", "video-001"], ["title", "My Video Updated"]]
// Event 1 is replaced, only Event 2 exists

Notes

  • The d-tag value should be stable across republishes (use content ID, not random)
  • Empty string ["d", ""] is valid but means only one event of that kind per pubkey
  • Regular replaceable events (Kind 0, 3, 10000-19999) don't need d-tag
  • This applies to ALL parameterized replaceable events, not just videos
  • Frontend caching may show old duplicates even after relay is cleaned - hard refresh

References

レビュー

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

同じリポジトリのスキル

概要と使いどころ

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月13日 更新

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月13日 更新

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月13日 更新

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月13日 更新

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月13日 更新

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月13日 更新

divinevideo のスキルをすべて見る

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