[{"data":1,"prerenderedAt":1456},["ShallowReactive",2],{"docs:\u002Fdocs\u002Ferrors":3,"docs:nav":1408},{"id":4,"title":5,"badge":6,"body":7,"description":1400,"extension":1401,"meta":1402,"navigation":364,"order":73,"path":1403,"section":1404,"seo":1405,"stem":1406,"__hash__":1407},"docs\u002Fdocs\u002Ferrors.md","Errors",null,{"type":8,"value":9,"toc":1390},"minimark",[10,24,29,39,49,62,92,95,251,255,279,502,506,705,709,712,825,829,844,850,854,860,866,884,891,895,1290,1297,1301,1386],[11,12,13,14,18,19,23],"p",{},"Error handling on this API has a wrinkle worth knowing about before you write your client. There are\n",[15,16,17],"strong",{},"two body formats",", and one class of endpoint returns failures with a ",[20,21,22],"code",{},"200",".",[25,26,28],"h2",{"id":27},"two-formats","Two formats",[11,30,31,34,35,38],{},[15,32,33],{},"Plain text"," — ",[20,36,37],{},"Content-Type: text\u002Fplain; charset=utf-8",", with a trailing newline. Used by\nauthentication failures, method-not-allowed, and all manifest errors:",[40,41,46],"pre",{"className":42,"code":44,"language":45},[43],"language-text","manifest: not found\n","text",[20,47,44],{"__ignoreMap":48},"",[11,50,51,34,54,57,58,61],{},[15,52,53],{},"JSON",[20,55,56],{},"Content-Type: application\u002Fjson",". Used by ",[20,59,60],{},"prepare-write",", cap rejections, and rate\nlimiting:",[40,63,67],{"className":64,"code":65,"language":66,"meta":48,"style":48},"language-json shiki shiki-themes github-dark-default github-dark-default","{ \"error\": \"redundancy 1.400 \u003C 1.5\" }\n","json",[20,68,69],{"__ignoreMap":48},[70,71,74,78,82,85,89],"span",{"class":72,"line":73},"line",1,[70,75,77],{"class":76},"sb7RM","{ ",[70,79,81],{"class":80},"sV7Mv","\"error\"",[70,83,84],{"class":76},": ",[70,86,88],{"class":87},"skZ57","\"redundancy 1.400 \u003C 1.5\"",[70,90,91],{"class":76}," }\n",[11,93,94],{},"A robust client checks the content type, or simply tries to parse JSON and falls back to the raw\ntext:",[40,96,100],{"className":97,"code":98,"language":99,"meta":48,"style":48},"language-ts shiki shiki-themes github-dark-default github-dark-default","async function readError(res: Response): Promise\u003Cstring> {\n  const text = await res.text()\n  try {\n    const parsed = JSON.parse(text)\n    return parsed.error ?? text\n  } catch {\n    return text.trim()\n  }\n}\n","ts",[20,101,102,146,169,178,200,215,226,239,245],{"__ignoreMap":48},[70,103,104,108,111,115,118,122,125,128,131,133,136,139,143],{"class":72,"line":73},[70,105,107],{"class":106},"srH4v","async",[70,109,110],{"class":106}," function",[70,112,114],{"class":113},"sYGIp"," readError",[70,116,117],{"class":76},"(",[70,119,121],{"class":120},"sAxfE","res",[70,123,124],{"class":106},":",[70,126,127],{"class":120}," Response",[70,129,130],{"class":76},")",[70,132,124],{"class":106},[70,134,135],{"class":120}," Promise",[70,137,138],{"class":76},"\u003C",[70,140,142],{"class":141},"sEQcL","string",[70,144,145],{"class":76},"> {\n",[70,147,149,152,155,158,161,164,166],{"class":72,"line":148},2,[70,150,151],{"class":106},"  const",[70,153,154],{"class":141}," text",[70,156,157],{"class":106}," =",[70,159,160],{"class":106}," await",[70,162,163],{"class":76}," res.",[70,165,45],{"class":113},[70,167,168],{"class":76},"()\n",[70,170,172,175],{"class":72,"line":171},3,[70,173,174],{"class":106},"  try",[70,176,177],{"class":76}," {\n",[70,179,181,184,187,189,192,194,197],{"class":72,"line":180},4,[70,182,183],{"class":106},"    const",[70,185,186],{"class":141}," parsed",[70,188,157],{"class":106},[70,190,191],{"class":141}," JSON",[70,193,23],{"class":76},[70,195,196],{"class":113},"parse",[70,198,199],{"class":76},"(text)\n",[70,201,203,206,209,212],{"class":72,"line":202},5,[70,204,205],{"class":106},"    return",[70,207,208],{"class":76}," parsed.error ",[70,210,211],{"class":106},"??",[70,213,214],{"class":76}," text\n",[70,216,218,221,224],{"class":72,"line":217},6,[70,219,220],{"class":76},"  } ",[70,222,223],{"class":106},"catch",[70,225,177],{"class":76},[70,227,229,231,234,237],{"class":72,"line":228},7,[70,230,205],{"class":106},[70,232,233],{"class":76}," text.",[70,235,236],{"class":113},"trim",[70,238,168],{"class":76},[70,240,242],{"class":72,"line":241},8,[70,243,244],{"class":76},"  }\n",[70,246,248],{"class":72,"line":247},9,[70,249,250],{"class":76},"}\n",[25,252,254],{"id":253},"the-200-with-an-error-case","The 200-with-an-error case",[256,257,260],"app-callout",{"title":258,"tone":259},"Check the body, not only the status","warn",[11,261,262,263,266,267,270,271,274,275,278],{},"Some endpoints write a JSON error object without setting a failure status, so a failed call arrives\nas ",[20,264,265],{},"200 OK"," with ",[20,268,269],{},"{\"error\": \"...\"}"," in the body. ",[20,272,273],{},"res.ok"," is therefore not a sufficient success\ncheck. Always inspect the parsed body for an ",[20,276,277],{},"error"," key. This affects operational endpoints more than\nthe core object path, but a client that checks both is correct everywhere and costs nothing.",[40,280,282],{"className":97,"code":281,"language":99,"meta":48,"style":48},"async function call(method: string, path: string, body?: unknown) {\n  const res = await signedFetch(method, path, body)\n  const text = await res.text()\n\n  if (!res.ok) throw new TesseraError(res.status, await readErrorFrom(text))\n\n  const parsed = text ? JSON.parse(text) : null\n  if (parsed && typeof parsed === 'object' && 'error' in parsed) {\n    throw new TesseraError(res.status, parsed.error) \u002F\u002F 200, but not a success\n  }\n  return parsed\n}\n",[20,283,284,327,344,360,366,401,405,433,467,483,488,497],{"__ignoreMap":48},[70,285,286,288,290,293,295,298,300,303,306,309,311,313,315,318,321,324],{"class":72,"line":73},[70,287,107],{"class":106},[70,289,110],{"class":106},[70,291,292],{"class":113}," call",[70,294,117],{"class":76},[70,296,297],{"class":120},"method",[70,299,124],{"class":106},[70,301,302],{"class":141}," string",[70,304,305],{"class":76},", ",[70,307,308],{"class":120},"path",[70,310,124],{"class":106},[70,312,302],{"class":141},[70,314,305],{"class":76},[70,316,317],{"class":120},"body",[70,319,320],{"class":106},"?:",[70,322,323],{"class":141}," unknown",[70,325,326],{"class":76},") {\n",[70,328,329,331,334,336,338,341],{"class":72,"line":148},[70,330,151],{"class":106},[70,332,333],{"class":141}," res",[70,335,157],{"class":106},[70,337,160],{"class":106},[70,339,340],{"class":113}," signedFetch",[70,342,343],{"class":76},"(method, path, body)\n",[70,345,346,348,350,352,354,356,358],{"class":72,"line":171},[70,347,151],{"class":106},[70,349,154],{"class":141},[70,351,157],{"class":106},[70,353,160],{"class":106},[70,355,163],{"class":76},[70,357,45],{"class":113},[70,359,168],{"class":76},[70,361,362],{"class":72,"line":180},[70,363,365],{"emptyLinePlaceholder":364},true,"\n",[70,367,368,371,374,377,380,383,386,389,392,395,398],{"class":72,"line":202},[70,369,370],{"class":106},"  if",[70,372,373],{"class":76}," (",[70,375,376],{"class":106},"!",[70,378,379],{"class":76},"res.ok) ",[70,381,382],{"class":106},"throw",[70,384,385],{"class":106}," new",[70,387,388],{"class":113}," TesseraError",[70,390,391],{"class":76},"(res.status, ",[70,393,394],{"class":106},"await",[70,396,397],{"class":113}," readErrorFrom",[70,399,400],{"class":76},"(text))\n",[70,402,403],{"class":72,"line":217},[70,404,365],{"emptyLinePlaceholder":364},[70,406,407,409,411,413,416,419,421,423,425,428,430],{"class":72,"line":228},[70,408,151],{"class":106},[70,410,186],{"class":141},[70,412,157],{"class":106},[70,414,415],{"class":76}," text ",[70,417,418],{"class":106},"?",[70,420,191],{"class":141},[70,422,23],{"class":76},[70,424,196],{"class":113},[70,426,427],{"class":76},"(text) ",[70,429,124],{"class":106},[70,431,432],{"class":141}," null\n",[70,434,435,437,440,443,446,449,452,455,458,461,464],{"class":72,"line":241},[70,436,370],{"class":106},[70,438,439],{"class":76}," (parsed ",[70,441,442],{"class":106},"&&",[70,444,445],{"class":106}," typeof",[70,447,448],{"class":76}," parsed ",[70,450,451],{"class":106},"===",[70,453,454],{"class":87}," 'object'",[70,456,457],{"class":106}," &&",[70,459,460],{"class":87}," 'error'",[70,462,463],{"class":106}," in",[70,465,466],{"class":76}," parsed) {\n",[70,468,469,472,474,476,479],{"class":72,"line":247},[70,470,471],{"class":106},"    throw",[70,473,385],{"class":106},[70,475,388],{"class":113},[70,477,478],{"class":76},"(res.status, parsed.error) ",[70,480,482],{"class":481},"sI3U9","\u002F\u002F 200, but not a success\n",[70,484,486],{"class":72,"line":485},10,[70,487,244],{"class":76},[70,489,491,494],{"class":72,"line":490},11,[70,492,493],{"class":106},"  return",[70,495,496],{"class":76}," parsed\n",[70,498,500],{"class":72,"line":499},12,[70,501,250],{"class":76},[25,503,505],{"id":504},"status-codes","Status codes",[507,508,509,525],"table",{},[510,511,512],"thead",{},[513,514,515,519,522],"tr",{},[516,517,518],"th",{},"Status",[516,520,521],{},"Meaning",[516,523,524],{},"Retry?",[526,527,528,548,560,575,588,601,614,627,639,651,664,680,693],"tbody",{},[513,529,530,535,545],{},[531,532,533],"td",{},[20,534,22],{},[531,536,537,538,541,542,544],{},"Success — ",[15,539,540],{},"unless"," the body carries an ",[20,543,277],{}," key.",[531,546,547],{},"—",[513,549,550,555,558],{},[531,551,552],{},[20,553,554],{},"201",[531,556,557],{},"Credential created.",[531,559,547],{},[513,561,562,567,573],{},[531,563,564],{},[20,565,566],{},"204",[531,568,569,570,23],{},"Success, no body. Deletes and ",[20,571,572],{},"auth\u002Fcheck",[531,574,547],{},[513,576,577,582,585],{},[531,578,579],{},[20,580,581],{},"400",[531,583,584],{},"Malformed request: bad JSON, bad hex, invalid geometry, missing slab.",[531,586,587],{},"No — fix the request.",[513,589,590,595,598],{},[531,591,592],{},[20,593,594],{},"401",[531,596,597],{},"Authentication failed.",[531,599,600],{},"Only after re-signing.",[513,602,603,608,611],{},[531,604,605],{},[20,606,607],{},"402",[531,609,610],{},"Storage cap exceeded.",[531,612,613],{},"No — needs a cap change or a deletion.",[513,615,616,621,624],{},[531,617,618],{},[20,619,620],{},"403",[531,622,623],{},"The resource belongs to another account.",[531,625,626],{},"No.",[513,628,629,634,637],{},[531,630,631],{},[20,632,633],{},"404",[531,635,636],{},"Not found for this account.",[531,638,626],{},[513,640,641,646,649],{},[531,642,643],{},[20,644,645],{},"405",[531,647,648],{},"Wrong HTTP method for the path.",[531,650,626],{},[513,652,653,658,661],{},[531,654,655],{},[20,656,657],{},"409",[531,659,660],{},"Slab still referenced by an object.",[531,662,663],{},"After deleting the object.",[513,665,666,671,674],{},[531,667,668],{},[20,669,670],{},"429",[531,672,673],{},"Rate limited.",[531,675,676,677,23],{},"Yes, after ",[20,678,679],{},"Retry-After",[513,681,682,687,690],{},[531,683,684],{},[20,685,686],{},"500",[531,688,689],{},"Server-side failure.",[531,691,692],{},"Yes, with backoff.",[513,694,695,700,703],{},[531,696,697],{},[20,698,699],{},"503",[531,701,702],{},"A subsystem is unavailable — often no providers right now.",[531,704,692],{},[25,706,708],{"id":707},"manifest-error-strings","Manifest error strings",[11,710,711],{},"Manifest errors arrive as plain text with these exact bodies. Match on them if you need to branch:",[507,713,714,725],{},[510,715,716],{},[513,717,718,721,723],{},[516,719,720],{},"Body",[516,722,518],{},[516,724,521],{},[526,726,727,741,755,769,783,797,811],{},[513,728,729,734,738],{},[531,730,731],{},[20,732,733],{},"manifest: not found",[531,735,736],{},[20,737,633],{},[531,739,740],{},"No such slab or object for this account.",[513,742,743,748,752],{},[531,744,745],{},[20,746,747],{},"manifest: forbidden for this account",[531,749,750],{},[20,751,620],{},[531,753,754],{},"It exists, but belongs to someone else.",[513,756,757,762,766],{},[531,758,759],{},[20,760,761],{},"manifest: invalid argument",[531,763,764],{},[20,765,581],{},[531,767,768],{},"Malformed field.",[513,770,771,776,780],{},[531,772,773],{},[20,774,775],{},"manifest: invalid erasure coding params",[531,777,778],{},[20,779,581],{},[531,781,782],{},"Geometry, duplicate provider, duplicate root, or key length.",[513,784,785,790,794],{},[531,786,787],{},[20,788,789],{},"manifest: slab still referenced by an object",[531,791,792],{},[20,793,657],{},[531,795,796],{},"Unpin blocked by a live reference.",[513,798,799,804,808],{},[531,800,801],{},[20,802,803],{},"manifest: empty account",[531,805,806],{},[20,807,581],{},[531,809,810],{},"No account resolved from the request.",[513,812,813,818,822],{},[531,814,815],{},[20,816,817],{},"manifest: object references missing slab",[531,819,820],{},[20,821,581],{},[531,823,824],{},"Register the slab first.",[25,826,828],{"id":827},"authentication-errors","Authentication errors",[11,830,831,832,834,835,840,841,23],{},"All ",[20,833,594],{},", all plain text. See\n",[836,837,839],"a",{"href":838},"\u002Fdocs\u002Fauthentication#failure-modes","Authentication § failure modes"," for what each one indicates and\nhow to debug ",[20,842,843],{},"signature mismatch",[40,845,848],{"className":846,"code":847,"language":45},[43],"missing auth params · invalid validUntil · signature expired\ninvalid credential  · unknown credential · invalid signature · signature mismatch\n",[20,849,847],{"__ignoreMap":48},[25,851,853],{"id":852},"rate-limiting","Rate limiting",[40,855,858],{"className":856,"code":857,"language":45},[43],"HTTP\u002F1.1 429 Too Many Requests\nRetry-After: 5\n\n{\"error\":\"rate limited\",\"retryAfter\":5}\n",[20,859,857],{"__ignoreMap":48},[11,861,862,863,865],{},"Honour ",[20,864,679],{},". Provisioning has its own limit with a distinct body:",[40,867,869],{"className":64,"code":868,"language":66,"meta":48,"style":48},"{ \"error\": \"rate limited: max 5 keys per hour\" }\n",[20,870,871],{"__ignoreMap":48},[70,872,873,875,877,879,882],{"class":72,"line":73},[70,874,77],{"class":76},[70,876,81],{"class":80},[70,878,84],{"class":76},[70,880,881],{"class":87},"\"rate limited: max 5 keys per hour\"",[70,883,91],{"class":76},[11,885,886,887,23],{},"See ",[836,888,890],{"href":889},"\u002Fdocs\u002Flimits","Limits",[25,892,894],{"id":893},"a-retry-policy-that-behaves","A retry policy that behaves",[40,896,898],{"className":97,"code":897,"language":99,"meta":48,"style":48},"const RETRYABLE = new Set([429, 500, 502, 503, 504])\n\nasync function withRetry\u003CT>(fn: () => Promise\u003CT>, attempts = 5): Promise\u003CT> {\n  let lastErr: unknown\n  for (let i = 0; i \u003C attempts; i++) {\n    try {\n      return await fn()\n    } catch (err) {\n      lastErr = err\n      const status = (err as TesseraError).status\n      if (!RETRYABLE.has(status)) throw err            \u002F\u002F 4xx: retrying cannot help\n\n      const retryAfter = (err as TesseraError).retryAfter\n      const backoff = retryAfter\n        ? retryAfter * 1000\n        : Math.min(2 ** i * 250, 8000) + Math.random() * 250   \u002F\u002F jitter matters\n      await new Promise((r) => setTimeout(r, backoff))\n    }\n  }\n  throw lastErr\n}\n",[20,899,900,941,945,1002,1015,1047,1054,1066,1076,1086,1107,1135,1139,1158,1171,1186,1239,1265,1271,1276,1285],{"__ignoreMap":48},[70,901,902,905,908,910,912,915,918,920,922,924,926,929,931,933,935,938],{"class":72,"line":73},[70,903,904],{"class":106},"const",[70,906,907],{"class":141}," RETRYABLE",[70,909,157],{"class":106},[70,911,385],{"class":106},[70,913,914],{"class":113}," Set",[70,916,917],{"class":76},"([",[70,919,670],{"class":141},[70,921,305],{"class":76},[70,923,686],{"class":141},[70,925,305],{"class":76},[70,927,928],{"class":141},"502",[70,930,305],{"class":76},[70,932,699],{"class":141},[70,934,305],{"class":76},[70,936,937],{"class":141},"504",[70,939,940],{"class":76},"])\n",[70,942,943],{"class":72,"line":148},[70,944,365],{"emptyLinePlaceholder":364},[70,946,947,949,951,954,956,959,962,965,967,970,973,975,977,979,982,985,987,990,992,994,996,998,1000],{"class":72,"line":171},[70,948,107],{"class":106},[70,950,110],{"class":106},[70,952,953],{"class":113}," withRetry",[70,955,138],{"class":76},[70,957,958],{"class":120},"T",[70,960,961],{"class":76},">(",[70,963,964],{"class":113},"fn",[70,966,124],{"class":106},[70,968,969],{"class":76}," () ",[70,971,972],{"class":106},"=>",[70,974,135],{"class":120},[70,976,138],{"class":76},[70,978,958],{"class":120},[70,980,981],{"class":76},">, ",[70,983,984],{"class":120},"attempts",[70,986,157],{"class":106},[70,988,989],{"class":141}," 5",[70,991,130],{"class":76},[70,993,124],{"class":106},[70,995,135],{"class":120},[70,997,138],{"class":76},[70,999,958],{"class":120},[70,1001,145],{"class":76},[70,1003,1004,1007,1010,1012],{"class":72,"line":180},[70,1005,1006],{"class":106},"  let",[70,1008,1009],{"class":76}," lastErr",[70,1011,124],{"class":106},[70,1013,1014],{"class":141}," unknown\n",[70,1016,1017,1020,1022,1025,1028,1031,1034,1037,1039,1042,1045],{"class":72,"line":202},[70,1018,1019],{"class":106},"  for",[70,1021,373],{"class":76},[70,1023,1024],{"class":106},"let",[70,1026,1027],{"class":76}," i ",[70,1029,1030],{"class":106},"=",[70,1032,1033],{"class":141}," 0",[70,1035,1036],{"class":76},"; i ",[70,1038,138],{"class":106},[70,1040,1041],{"class":76}," attempts; i",[70,1043,1044],{"class":106},"++",[70,1046,326],{"class":76},[70,1048,1049,1052],{"class":72,"line":217},[70,1050,1051],{"class":106},"    try",[70,1053,177],{"class":76},[70,1055,1056,1059,1061,1064],{"class":72,"line":228},[70,1057,1058],{"class":106},"      return",[70,1060,160],{"class":106},[70,1062,1063],{"class":113}," fn",[70,1065,168],{"class":76},[70,1067,1068,1071,1073],{"class":72,"line":241},[70,1069,1070],{"class":76},"    } ",[70,1072,223],{"class":106},[70,1074,1075],{"class":76}," (err) {\n",[70,1077,1078,1081,1083],{"class":72,"line":247},[70,1079,1080],{"class":76},"      lastErr ",[70,1082,1030],{"class":106},[70,1084,1085],{"class":76}," err\n",[70,1087,1088,1091,1094,1096,1099,1102,1104],{"class":72,"line":485},[70,1089,1090],{"class":106},"      const",[70,1092,1093],{"class":141}," status",[70,1095,157],{"class":106},[70,1097,1098],{"class":76}," (err ",[70,1100,1101],{"class":106},"as",[70,1103,388],{"class":120},[70,1105,1106],{"class":76},").status\n",[70,1108,1109,1112,1114,1116,1119,1121,1124,1127,1129,1132],{"class":72,"line":490},[70,1110,1111],{"class":106},"      if",[70,1113,373],{"class":76},[70,1115,376],{"class":106},[70,1117,1118],{"class":141},"RETRYABLE",[70,1120,23],{"class":76},[70,1122,1123],{"class":113},"has",[70,1125,1126],{"class":76},"(status)) ",[70,1128,382],{"class":106},[70,1130,1131],{"class":76}," err            ",[70,1133,1134],{"class":481},"\u002F\u002F 4xx: retrying cannot help\n",[70,1136,1137],{"class":72,"line":499},[70,1138,365],{"emptyLinePlaceholder":364},[70,1140,1142,1144,1147,1149,1151,1153,1155],{"class":72,"line":1141},13,[70,1143,1090],{"class":106},[70,1145,1146],{"class":141}," retryAfter",[70,1148,157],{"class":106},[70,1150,1098],{"class":76},[70,1152,1101],{"class":106},[70,1154,388],{"class":120},[70,1156,1157],{"class":76},").retryAfter\n",[70,1159,1161,1163,1166,1168],{"class":72,"line":1160},14,[70,1162,1090],{"class":106},[70,1164,1165],{"class":141}," backoff",[70,1167,157],{"class":106},[70,1169,1170],{"class":76}," retryAfter\n",[70,1172,1174,1177,1180,1183],{"class":72,"line":1173},15,[70,1175,1176],{"class":106},"        ?",[70,1178,1179],{"class":76}," retryAfter ",[70,1181,1182],{"class":106},"*",[70,1184,1185],{"class":141}," 1000\n",[70,1187,1189,1192,1195,1198,1200,1203,1206,1208,1210,1213,1215,1218,1221,1224,1226,1229,1232,1234,1236],{"class":72,"line":1188},16,[70,1190,1191],{"class":106},"        :",[70,1193,1194],{"class":76}," Math.",[70,1196,1197],{"class":113},"min",[70,1199,117],{"class":76},[70,1201,1202],{"class":141},"2",[70,1204,1205],{"class":106}," **",[70,1207,1027],{"class":76},[70,1209,1182],{"class":106},[70,1211,1212],{"class":141}," 250",[70,1214,305],{"class":76},[70,1216,1217],{"class":141},"8000",[70,1219,1220],{"class":76},") ",[70,1222,1223],{"class":106},"+",[70,1225,1194],{"class":76},[70,1227,1228],{"class":113},"random",[70,1230,1231],{"class":76},"() ",[70,1233,1182],{"class":106},[70,1235,1212],{"class":141},[70,1237,1238],{"class":481},"   \u002F\u002F jitter matters\n",[70,1240,1242,1245,1247,1249,1252,1255,1257,1259,1262],{"class":72,"line":1241},17,[70,1243,1244],{"class":106},"      await",[70,1246,385],{"class":106},[70,1248,135],{"class":141},[70,1250,1251],{"class":76},"((",[70,1253,1254],{"class":120},"r",[70,1256,1220],{"class":76},[70,1258,972],{"class":106},[70,1260,1261],{"class":113}," setTimeout",[70,1263,1264],{"class":76},"(r, backoff))\n",[70,1266,1268],{"class":72,"line":1267},18,[70,1269,1270],{"class":76},"    }\n",[70,1272,1274],{"class":72,"line":1273},19,[70,1275,244],{"class":76},[70,1277,1279,1282],{"class":72,"line":1278},20,[70,1280,1281],{"class":106},"  throw",[70,1283,1284],{"class":76}," lastErr\n",[70,1286,1288],{"class":72,"line":1287},21,[70,1289,250],{"class":76},[11,1291,1292,1293,1296],{},"Two things this gets right that naive retry loops do not: it refuses to retry ",[20,1294,1295],{},"4xx"," responses, where\nthe answer will not change, and it adds jitter, so a fleet of clients recovering from an outage does\nnot synchronise into a thundering herd.",[25,1298,1300],{"id":1299},"errors-worth-special-handling","Errors worth special handling",[507,1302,1303,1313],{},[510,1304,1305],{},[513,1306,1307,1310],{},[516,1308,1309],{},"Situation",[516,1311,1312],{},"Right response",[526,1314,1315,1328,1339,1349,1363,1373],{},[513,1316,1317,1325],{},[531,1318,1319,1322,1323],{},[20,1320,1321],{},"503 no contracted hosts available"," from ",[20,1324,60],{},[531,1326,1327],{},"Backoff and retry. Transient provider availability, not a client bug.",[513,1329,1330,1333],{},[531,1331,1332],{},"Shard write fails at a provider",[531,1334,1335,1336,1338],{},"Get a replacement provider from ",[20,1337,60],{},"; do not retry the same one indefinitely.",[513,1340,1341,1346],{},[531,1342,1343],{},[20,1344,1345],{},"402 storage cap exceeded",[531,1347,1348],{},"Stop, alert an operator. Never retry on a loop.",[513,1350,1351,1356],{},[531,1352,1353],{},[20,1354,1355],{},"401 signature expired",[531,1357,1358,1359,1362],{},"Re-sign with a fresh ",[20,1360,1361],{},"validUntil",". If it recurs, check clock skew on your host.",[513,1364,1365,1370],{},[531,1366,1367],{},[20,1368,1369],{},"409 slab still referenced",[531,1371,1372],{},"Delete referencing objects, then prune.",[513,1374,1375,1383],{},[531,1376,1377,1379,1380,1382],{},[20,1378,22],{}," with an ",[20,1381,277],{}," key",[531,1384,1385],{},"Treat as the failure it is; log the endpoint, since this is the easiest failure to swallow accidentally.",[1387,1388,1389],"style",{},"html pre.shiki code .sb7RM, html code.shiki .sb7RM{--shiki-default:#E6EDF3;--shiki-dark:#E6EDF3}html pre.shiki code .sV7Mv, html code.shiki .sV7Mv{--shiki-default:#7EE787;--shiki-dark:#7EE787}html pre.shiki code .skZ57, html code.shiki .skZ57{--shiki-default:#A5D6FF;--shiki-dark:#A5D6FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .srH4v, html code.shiki .srH4v{--shiki-default:#FF7B72;--shiki-dark:#FF7B72}html pre.shiki code .sYGIp, html code.shiki .sYGIp{--shiki-default:#D2A8FF;--shiki-dark:#D2A8FF}html pre.shiki code .sAxfE, html code.shiki .sAxfE{--shiki-default:#FFA657;--shiki-dark:#FFA657}html pre.shiki code .sEQcL, html code.shiki .sEQcL{--shiki-default:#79C0FF;--shiki-dark:#79C0FF}html pre.shiki code .sI3U9, html code.shiki .sI3U9{--shiki-default:#8B949E;--shiki-dark:#8B949E}",{"title":48,"searchDepth":171,"depth":171,"links":1391},[1392,1393,1394,1395,1396,1397,1398,1399],{"id":27,"depth":148,"text":28},{"id":253,"depth":148,"text":254},{"id":504,"depth":148,"text":505},{"id":707,"depth":148,"text":708},{"id":827,"depth":148,"text":828},{"id":852,"depth":148,"text":853},{"id":893,"depth":148,"text":894},{"id":1299,"depth":148,"text":1300},"Status codes, the two different error body formats, and the one case where a failure arrives with a 200.","md",{},"\u002Fdocs\u002Ferrors","Reference",{"title":5,"description":1400},"docs\u002Ferrors","ovXXkS8pSG2CUdIAmUVAR73S_04fw12TknuSir02llM",[1409,1414,1418,1422,1426,1430,1435,1440,1441,1445,1448,1452],{"path":1410,"title":1411,"description":1412,"section":1413,"order":202,"badge":6},"\u002Fdocs\u002Fapi\u002Faccount","Account","GET \u002Faccount — stored, read, and written byte counters for your credential.","API reference",{"path":1415,"title":1416,"description":1417,"section":1413,"order":180,"badge":6},"\u002Fdocs\u002Fapi\u002Fobjects","Objects","Register, read, list, and delete objects — ordered lists of slab segments with encrypted keys and opaque metadata.",{"path":1419,"title":1420,"description":1421,"section":1413,"order":148,"badge":6},"\u002Fdocs\u002Fapi\u002Fplacement","Placement","POST \u002Fprepare-write — get the providers, contracts, and access tokens for writing a slab's shards.",{"path":1423,"title":1424,"description":1425,"section":1413,"order":73,"badge":6},"\u002Fdocs\u002Fapi\u002Fprovisioning","Credentials","Provision, verify, and revoke the ed25519 credential that is both your API identity and your account.",{"path":1427,"title":1428,"description":1429,"section":1413,"order":171,"badge":6},"\u002Fdocs\u002Fapi\u002Fslabs","Slabs","Register, read, list, unpin, and prune erasure-coded slabs — the layer that records which provider holds which shard.",{"path":1431,"title":1432,"description":1433,"section":1434,"order":148,"badge":6},"\u002Fdocs\u002Fauthentication","Authentication","Every request is signed with ed25519 over a blake2b hash of the method, host, path, expiry, and body. Here is the exact construction, with working code.","Guides",{"path":1436,"title":1437,"description":1438,"section":1439,"order":148,"badge":6},"\u002Fdocs\u002Fconcepts","Concepts & data model","Sectors, shards, slabs, objects, and accounts — what each one is, why the model has no filenames, and what that means for your integration.","Introduction",{"path":1403,"title":5,"description":1400,"section":1404,"order":73,"badge":6},{"path":1442,"title":1443,"description":1444,"section":1439,"order":73,"badge":6},"\u002Fdocs","Overview","Tessera is an HTTP API for storing encrypted, erasure-coded objects across independent storage providers. This is the reference for it.",{"path":889,"title":1446,"description":1447,"section":1404,"order":148,"badge":6},"Limits & quotas","Rate limits, storage caps, geometry constraints, and the size and encoding limits that apply to every request.",{"path":1449,"title":1450,"description":1451,"section":1434,"order":73,"badge":6},"\u002Fdocs\u002Fquickstart","Quickstart","Provision a credential, upload an object across 15 providers, and read it back. Fifteen minutes, one file of code.",{"path":1453,"title":1454,"description":1455,"section":1434,"order":171,"badge":6},"\u002Fdocs\u002Frecovery","Recovery without Tessera","How to retrieve your data if Tessera is unavailable, unwilling, or permanently gone — and what you need to keep on hand for that to work.",1786190913584]