{"record":{"id":"d29e53bdafc8ad83","repo":"koala73/worldmonitor","slug":"invalid-portwatch-canonical-snapshot","errorCode":null,"errorMessage":"Invalid PortWatch canonical snapshot","messagePattern":"Invalid PortWatch canonical snapshot","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/seed-portwatch-port-activity.mjs","lineNumber":1741,"sourceCode":"      await extendExistingTtl([CANONICAL_KEY, META_KEY, ...prevCountryKeys], TTL);\n      if (previousRead) await publishPortActivitySnapshot({\n        countryData: new Map(),\n        canonicalAdvances: false,\n        metaPayload: buildPortActivityFailureMeta(previousMeta, { reason: new Error('SIGTERM') }),\n      });\n    } catch {}\n    try { await releaseLock(LOCK_DOMAIN, runId); } catch {}\n    process.exit(1);\n  };\n  process.on('SIGTERM', onSigterm);\n  process.on('SIGINT', onSigterm);\n\n  try {\n    const prevIso2List = await readSeedSnapshot(CANONICAL_KEY, { strict: true });\n    previousMeta = await readSeedSnapshot(META_KEY, { strict: true });\n    if (prevIso2List !== null && (!Array.isArray(prevIso2List)\n      || prevIso2List.some((iso2) => typeof iso2 !== 'string' || !/^[A-Z]{2}$/.test(iso2)))) {\n      throw new Error('Invalid PortWatch canonical snapshot');\n    }\n    if (previousMeta !== null && (typeof previousMeta !== 'object' || Array.isArray(previousMeta))) {\n      throw new Error('Invalid PortWatch seed metadata');\n    }\n    previousRead = true;\n    prevCountryKeys = Array.isArray(prevIso2List) ? prevIso2List.map(iso2 => `${KEY_PREFIX}${iso2}`) : [];\n\n    console.log(`  Fetching port activity data (60d: last30 + prev30 windows)...`);\n    const {\n      countries,\n      countryData,\n      servedStaleCount,\n      droppedTooOldCount,\n      droppedNoCacheCount,\n      freshFetchedCount,\n      cacheHitCount,\n      retryState,\n      coverage,","sourceCodeStart":1723,"sourceCodeEnd":1759,"githubUrl":"https://github.com/koala73/worldmonitor/blob/7d06c8633d256c18e38133030bc3613976a96ec9/scripts/seed-portwatch-port-activity.mjs#L1723-L1759","documentation":"On startup the PortWatch seed script reads its canonical snapshot (the list of ISO2 country codes seeded last time) from the seed snapshot store in strict mode. If the stored value is not null and is not an array of valid two-letter uppercase ISO2 codes, the script refuses to continue with 'Invalid PortWatch canonical snapshot', because the previous canonical state cannot be trusted for diffing/cleanup.","triggerScenarios":"readSeedSnapshot(CANONICAL_KEY, { strict: true }) returns a value that is not an array, or an array containing entries that are not strings matching /^[A-Z]{2}$/ — e.g. corrupted snapshot storage, hand-edited seed metadata, or a snapshot written by a different schema.","commonSituations":"Snapshot file/Redis entry corrupted by an interrupted write; someone manually edited the canonical snapshot; a refactor changed the snapshot shape (e.g. storing objects instead of ISO2 strings) while old data lingers; wrong key restored from backup.","solutions":["Delete/reset the canonical snapshot for CANONICAL_KEY so the seed rebuilds state from scratch","Re-derive the canonical ISO2 list from current cache keys (KEY_PREFIX*) and rewrite the snapshot","Verify the snapshot writer still emits string arrays of ISO2 codes matching /^[A-Z]{2}$/","Restore the snapshot from a known-good backup taken after a successful seed"],"exampleFix":"// before (hand-edited snapshot)\n[\"us\", \"de\", \"jp\"]\n// after\n[\"US\", \"DE\", \"JP\"]","handlingStrategy":"validation","validationCode":"const prev = await readSeedSnapshot(CANONICAL_KEY, { strict: false });\nif (prev !== null && (!Array.isArray(prev) || prev.some((c) => typeof c !== 'string' || !/^[A-Z]{2}$/.test(c)))) {\n  await clearSeedSnapshot(CANONICAL_KEY);\n}","typeGuard":"const isValidIso2List = (v) => v === null || (Array.isArray(v) && v.every((c) => typeof c === 'string' && /^[A-Z]{2}$/.test(c)));","tryCatchPattern":"try {\n  await runSeed();\n} catch (err) {\n  if (err.message === 'Invalid PortWatch canonical snapshot') {\n    await resetCanonicalSnapshot();\n    await runSeed();\n  } else throw err;\n}","preventionTips":["Never hand-edit seed snapshots","Wrap snapshot writes in atomic operations to avoid partial writes","Validate snapshot shape at write time, not only at read time"],"tags":["seed","validation","snapshot"],"backgroundTag":"schema-validation-failed","analyzedSha":"7d06c8633d256c18e38133030bc3613976a96ec9","analyzedAt":"2026-09-15T16:44:39.439Z","contentChangedAt":"2026-09-15T16:44:39.439Z","schemaVersion":2},"datasetVersion":"2026-09-15T18:17:12.389Z"}