Troubleshooting

Every error is JSON: {"error": {"type": "...", "message": "..."}}. The message says what to fix.

You seeWhyFix
401 authentication_errorno Authorization: Bearer header, a mistyped key, or a revoked keycheck echo $JEPELA_API_KEY; ask the gateway owner for a new key
402 payment_requiredthe tenant's credit is used up, or a card refund or dispute took credit back below zero (see Pricing)the owner adds credit with credit add; reads (/v1/models, /v1/usage) still work, and so does removing data (forget, delete and the other delete routes)
403 account_suspendedthe account is suspended (by Jepela, or by your own deletion request until it is erased) or erasedwhile suspended, your keys can still read your data (every GET route) and remove it (forget, delete and the other delete routes), and nothing else; write to Jepela. An erased account's keys do nothing
400 Content-Length is not a numbera broken client or proxysend a correct Content-Length
400 the body could not be decompressed as gzip (or zstd)the body says Content-Encoding but is not compressed that way, was cut short, or holds more than 64 gzip members (a zstd body cut short may get 422 invalid JSON instead)send the compressed bytes whole, as one gzip member, or drop the header
400 the JSON is nested more than 100 levels deeparrays or objects inside each other more than 100 levels (counted on the whole body, or on each line of a JSON Lines batch)send a flatter state; no real request comes near the limit
413the body is over 1 MB (16 MB for /v1/batches and /v1/golden); a compressed body counts once decompressedsend less state; the engine's window is smaller than that anyway
415missing Content-Type: application/jsonadd the header (curl needs -H "Content-Type: application/json")
415 Content-Encoding ... is not accepted or 415 one Content-Encoding onlya body compressed with br, deflate or another encoding, or compressed twicecompress once with gzip or zstd, or send it plain
422 ... state must be non-empty text ...empty state, or a numbersend a string, an object or an array of strings
422 ... questions must be a nonempty mappingquestions missing or emptyat least one question
422 ... type must be choice, score, or noula typo in typeone of the three
422 ... choice needs 1 to 255 named candidatescriteria missing, empty or too biga map of option name to description
422 ... score needs 2 to 10 ordered levelscriteria is not a list of 2 to 10a list, low to high
422 ... a noul's criteria is an object with a true and a false descriptiona noul's criteria has other keys{"true": ..., "false": ...}, or leave it out
422 this request needs N engine questions; the limit per request is 400too many questions, option orders or large choices in one requestsplit the request, or ask fewer orders
422 ... instructions are requiredno instructionsadd the question text (a string, object or array)
422 unknown model ...a model name Jepela does not havethe message lists the names; jepela-latest always works
422 unknown model 'jev-latest' is a Jev model name ...code written for Jev, whose SDK asks for jev-latestset the model to jepela
422 subject must be ...a subject id with spaces, slashes or over 36 charactersletters, digits, underscore, hyphen
422 memory.top_k must be ... or memory.min_share ...top_k not a whole number 1 to 20, min_share not 0.05 to 1fix the number
422 derive: ..., or from POST /v1/memory/rules 422 the name ... is not allowed or ... is not allowed in a conditionan expression uses a name or function that is not allowed, reads a field or an index from a value ([1, 2][0]), or cannot be evaluated on this request (a missing field, a number it cannot read)comparisons, arithmetic, and/or/not and the listed functions only, fields read from paths such as reading.t or items[0] (Request options)
422 method is auto (the default), engine or match, or method match answers choice questions onlya misspelt method, or match on a request with only scores and yes/no questionssee Request options
422 robust.orders must be a whole number from 1 to 5, robust must be true or an object ..., windows must be true or an object ..., windows.combine maps question ids to one of max, mean, mina malformed robust or windowssee Request options
422 values is an object of at most 50 fieldsvalues is not an object, or too bigsend only the fields derive and rules use
422 a memory line is at most 2000 characters; ...one line of remember is too long; nothing was storedsplit it into facts, one per line
422 a rule's text is non-empty and at most 500 charactersan empty or long rule textone short sentence of what to do
422 text must not be empty or concept must not be emptyremember without text, or forget without a conceptsend the text or the concept
422 context is built by Jepela ...the request sent contextsend subject, derive and values; Jepela builds the context
422 assets: Jepela reads text only, not images ... (or images, or questions.<id>.assets)the request, a question, or a golden case carries pictures, as Jev takes them; nothing was chargeddescribe what the picture shows in the state, and leave the field out
422 ttl_seconds: remember stores lines that are recalled by their words ... (or when, pin, exclude, question, expires)remember was sent what only a rule can honour: a condition, an expiry, a pin or an exclusion; nothing was stored or chargedsend the line to POST /v1/memory/rules
422 concept: POST /v1/memory/delete reads only subject ...delete was sent a field that asks for less than everything (a concept, a rule id); nothing was deletedforget with concept for one fact, POST /v1/memory/rules/delete for one rule, or delete with subject alone
422 id: without ids POST /v1/golden/delete deletes every golden case ... or 422 decision_id: POST /v1/decisions/delete reads no field ...a field asked for less than everything, which these routes cannot do; nothing was deletedsend ids to delete some golden cases; {} to delete everything
422 question limits an exclusion to one question ...a rule with question and no exclude; nothing was storedleave question out, or add exclude
403 signup_disabled or invite_requiredself-serve sign-up is off, or needs a codeask the gateway owner
404 no such decision and questiona decision_id from another tenant, a typo, or older than 30 daysfeedback within 30 days, with the id the decision returned
409 conflicta limit: 5,000 golden cases, a subject's 10,000 memory lines (subject '...' holds N lines ...; nothing was stored) or at most 100 rules per subjectdelete cases, forget lines, or delete rules first
409 from POST /v1/finetuneanother of your fine-tuning jobs is running, or the engine is off; it has to be on to trainwait for the job (GET /v1/finetune), or try again later
422 you have N labelled cases ...; fine-tuning needs at least 20 ...too few golden cases with expected answersadd cases with POST /v1/golden
422 invalid JSON ... or duplicate JSON keymalformed body, or the same key twicevalidate the JSON; JSON with duplicate keys is rejected on purpose
429 rate_limit_error with Retry-Afterover the account's requests per minute (all its keys together), or too many sign-ups from this address todaywait the seconds given; the SDKs retry by themselves
502 engine_error with the engine is offthe engine is switched offtry again later; the SDKs retry with backoff; nothing was charged
502 engine_errorthe engine or the memory service behind the gateway is down or answered an errorcheck GET /health; nothing was charged
500 server_errorthe gateway failed; the message names only the error type (request failed: ...) and the gateway writes no logtell the gateway owner the time and the request; nothing was charged

The answer is not what you expected

  • A choice picks the least bad option. Add other or none_of_these. Overlapping descriptions split the probability; make options exclusive.
  • A score sits in the middle for everything. Levels written as degree words ("moderate", "severe") do not separate; write each level as a situation ("a workaround exists", "no workaround"). A score over a whole document is blunt; ask per-claim Nouls instead.
  • A noul is near 0.5. The engine cannot tell from the state. Add the fact that decides it to the state, or to the subject's memory, and ask a narrower question.
  • The answer has an unknown_field warning. The request, its memory or a question has a field Jepela does not read, and the answer was made without it; the message names the closest field it reads. A misspelt subject (subjet) gives a decision without memory, so the answer has no memory block; fix the name and send it again. The memory routes warn the same way: a rule with ttl_secs was stored without an expiry (delete it with POST /v1/memory/rules/delete and add it again with ttl_seconds).
  • The memory did not change anything. Check memory.lines_used and memory.lines_seen. Zero used means recall found no line sharing words with the state, the subject's names or the question: put the subject's name and your states' vocabulary in the lines, add the names the subject goes by with POST /v1/memory/aliases, or pin a line that must always count. Fewer seen than used means the lines and the state together are longer than the engine reads; each line in memory.hits and memory.rules_fired says with read whether it was read. In an array Jepela leaves out the oldest elements so that the lines are read (reading.turns_dropped), so there fewer seen means the lines and the newest element alone are longer than the engine reads: send shorter lines. lines_dropped counts lines that did not fit in its 64 context lines. Use compare: true to see the two answers side by side, explain: true to see how far each line moved them, and placebo: true to see whether a change came from what the lines say.
  • A rule in memory is ignored or backfires. The engine does not compare numbers or read negation: "never 17" makes 17 more likely, "stop below 30" is answered by its words. Remove options that must never be chosen in code (an exclusion rule, or leave them out of the question), write what to do, and put conditions in a rule with when so they are checked in code (Rules in memory). The warnings say when a line has this problem.
  • The answer ignores the end of a long state. The engine read only the start: usage.state_truncated is true and there is a state_cut warning. Send the part that matters first, or "windows": true. An array is the other way round: the engine reads its newest elements and cuts the oldest, so put what matters last; with memory or computed lines, Jepela leaves out the oldest elements so that the lines are read, and reading.turns_dropped and the state_cut warning say how many. With windows, an array longer than 16 windows is read from its end, so it also loses its oldest elements, never its newest.
  • A large choice picks strangely. Above 20 options the answer is matched by default ("method": "match" in the answer): give each option a short description of what it means, since an option without one is matched by its name alone. With "method": "engine" it comes from two rounds (rounds: 2) in groups that follow the order you wrote, and "robust": true does not apply; a hierarchy of smaller choices is usually clearer. Up to 20 options, if the answer changes when you reorder them, use "robust": true.
  • A request takes longer than usual. The engine loads its three checkpoints when it starts (load_seconds in the engine's /health); only a tenant's fine-tuned checkpoint loads on its first request. After that requests take tens of milliseconds; usage.engine_ms says where the time goes.
  • The memory changed an answer it should not have. Lines are recalled by shared words, so a line about another topic can come along. Try "memory": {"focus": true}, which keeps only lines that share a word with the state beyond the subject's name, or raise min_share.