{"record":{"id":"dee2311524c9c567","repo":"FuelLabs/fuels-ts","slug":"duplicated-policy","errorCode":"DUPLICATED_POLICY","errorMessage":"Duplicate policy type found: ${PolicyType.MaxFee}","messagePattern":"Duplicate policy type found: (.+?)","errorType":"exception","errorClass":"FuelError","httpStatus":null,"severity":"error","filePath":"packages/transactions/src/coders/policy.ts","lineNumber":62,"sourceCode":"export type PolicyMaxFee = {\n  type: PolicyType.MaxFee;\n  data: BN;\n};\n\nexport type PolicyOwner = {\n  type: PolicyType.Owner;\n  data: BN;\n};\n\nexport const sortPolicies = (policies: Policy[]): Policy[] =>\n  policies.sort((a, b) => a.type - b.type);\n\nfunction validateDuplicatedPolicies(policies: Policy[]): void {\n  const seenTypes = new Set<PolicyType>();\n\n  policies.forEach((policy) => {\n    if (seenTypes.has(policy.type)) {\n      throw new FuelError(\n        ErrorCode.DUPLICATED_POLICY,\n        `Duplicate policy type found: ${PolicyType.MaxFee}`\n      );\n    }\n    seenTypes.add(policy.type);\n  });\n}\n\nexport function getPolicyTypesArray(policyTypes: number): number[] {\n  const out: number[] = [];\n  let m = policyTypes >>> 0;\n  while (m !== 0) {\n    const low = m & -m;\n    out.push(low);\n    m &= m - 1;\n  }\n  return out;\n}","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/FuelLabs/fuels-ts/blob/b3f37c91aca4aa9d5e4c0d3967f66237190826ea/packages/transactions/src/coders/policy.ts#L44-L80","documentation":"Thrown by validateDuplicatedPolicies() when two or more policies in the supplied array share the same PolicyType. Each policy type may appear at most once in a transaction's policy list. NOTE a message bug: the text always interpolates PolicyType.MaxFee (a constant) regardless of which type actually duplicated, so 'MaxFee' in the message may be misleading.","triggerScenarios":"Passing a policies array with two entries of the same type, e.g. [{type: PolicyType.MaxFee,...},{type: PolicyType.MaxFee,...}] or two Tip policies; building policies from a map/list without deduping by type.","commonSituations":"Merging policy lists from multiple sources that both set MaxFee/Tip; default policy plus a user override both present; programmatically pushing a policy that already exists.","solutions":["Dedupe policies by type before encoding (keep the last/merged value per type).","Inspect the full policies array rather than trusting the 'MaxFee' label in the message, since the message is hardcoded.","Build policies through a single source/map keyed by PolicyType to avoid accidental duplicates."],"exampleFix":"// before\nconst policies = [\n  { type: PolicyType.MaxFee, data: bn(100) },\n  { type: PolicyType.MaxFee, data: bn(200) },\n];\n\n// after — dedupe by type\nconst byType = new Map(policies.map(p => [p.type, p]));\nconst deduped = [...byType.values()];","handlingStrategy":"validation","validationCode":"import { PolicyType, type Policy } from '@fuel-ts/transactions';\n\nfunction dedupePolicies(policies: Policy[]): Policy[] {\n  const map = new Map<PolicyType, Policy>();\n  for (const p of policies) map.set(p.type, p); // last wins\n  return [...map.values()];\n}\n\nconst clean = dedupePolicies(policies);","typeGuard":"function hasUniquePolicyTypes(policies: Policy[]): boolean {\n  return new Set(policies.map(p => p.type)).size === policies.length;\n}","tryCatchPattern":"try {\n  validateDuplicatedPolicies(policies);\n} catch (e) {\n  if (e instanceof FuelError && e.code === ErrorCode.DUPLICATED_POLICY) {\n    // NOTE: message always says 'MaxFee'; dedupe by actual type and retry\n    policies = dedupePolicies(policies);\n  } else throw e;\n}","preventionTips":["Build policies from a single Map keyed by PolicyType to avoid duplicates.","Do not trust the 'MaxFee' text in the message — inspect the array directly.","Dedupe before encoding whenever merging policy sources."],"tags":["policy","validation","transaction","typescript"],"backgroundTag":null,"analyzedSha":"b3f37c91aca4aa9d5e4c0d3967f66237190826ea","analyzedAt":"2026-08-12T20:30:56.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}