Installing and configuring
Why does pip install hollerith not work?
The SDK is not on PyPI and is not planned to be. It is served as a wheel from the deployment
you use.
Why does Hollerith() raise a plain ValueError?
There is no default API origin. If neither base_url= nor HOLLERITH_BASE_URL is set, the
constructor raises a bare ValueError — not a HollerithError, so an except HollerithError
block will not catch it.
Why did I get invalid_api_key from a snippet I copied?
The console Quickstart shows the key as hk_live_… with a Unicode ellipsis, and the docs do
the same. Pasted unchanged, that string is sent as your key and fails
authentication. Replace the whole placeholder with the key from the API Keys tab.
Speed
Why is my first request slow?
One GPU worker serves the queue. If it is starting or rolling out, a poll returns a retryable503 and the SDK waits through it rather than raising. An idle worker also polls for queued
work on an interval — 60 seconds in the default configuration — so a job can sit queued that
long before it is claimed.
timeout=900.0 seconds and raise TimeoutError.
Why did predict take as long as fit?
Because no fitted context was bound, so predict re-sent the training table alongside the
rows to score. Three ways that happens:
server_context=Falseon the constructor, which disables fitted contexts entirely.fit(..., wait=False), which returns before the context binds. See the next entry.- A custom
transport=that does not implementsubmit_fit.
FitHandle, build a client from its id.
Why did wait=False drop what I asked for?
wait=False returns a handle the moment the job is submitted, and every step the SDK would
have run after the wait is skipped. Three things go with it, none of them warned about:
- The fitted context is not bound.
fitted_context_id_staysNone, so the nextpredictre-uploads the training table.handle.wait()does not bind it either. fit(evaluate=True)is silently dropped. The evaluation job is never submitted, and there is no error.predict(quantiles=[...])returns no DataFrame. Call.wait()and build the frame from.predictions,.quantilesand.quantile_levelsyourself.
Task inference
Why did my integer column become a classification?
An integral numeric target with 20 or fewer distinct values is read as class labels. A 1–10 rating, a 0/1 flag and a small count all become classification without a warning.task= always wins over the inferred choice.
Why does predict say schema_mismatch?
The rows you passed do not carry every column fit saw. Extra columns are dropped silently;
missing ones are the error.
- The
causefield names both column sets — the featuresfitsaw, and the columns you sent. - An array is checked by column count only, and assumes the order seen at fit time.
Size and schema limits
Why does dataset_too_large fire below 1,000,000 rows?
Rows, columns and their product each have a ceiling. A table has to be under all three, so
100,000 rows × 2,000 columns breaches the 100,000,000-cell budget even though neither the row
nor the column limit is reached. See Limits and quotas.
Why does the SDK reject a dataset my deployment allows?
Client-side limits come from a snapshot bundled in the wheel, not fromGET /v1/model-limits.
If your deployment’s limits were raised, the wheel has to be upgraded before the SDK will
submit against them.
Reading results
Why does result[0.1] raise a KeyError?
Quantile column labels are strings, not floats. predict(quantiles=[0.1, 0.5, 0.9]) returns
columns ["prediction", "0.1", "0.5", "0.9"].
Why did predict_proba change the order of classes_?
It adopts the engine’s class ordering and overwrites classes_ so the two stay aligned.
Column j of the returned array matches clf.classes_[j] as read after the call, not before.
Evaluation
Why is my holdout metric so much worse than my k-fold metric?
Training takes the first 80% of rows in file order and the holdout is the last 20%. Nothing shuffles. A CSV sorted by its target trains on some classes and scores on others, which makes the metric meaningless.- Method is chosen by row count — 10,000 rows or fewer get k-fold, above that gets holdout.
- Shuffle the file before evaluating a large sorted table.
Fitted contexts
Why is my fitted context gone?
A context expires 7 days after the fit that created it. Using it does not extend that, and after it lapses you getfitted_context_expired (404).
- Every
fitcreates a new context. Nothing is reused between fits. fitted_context_expires_at_holds the deadline for the one currently bound.
Why can’t I call evaluate() after from_fitted_context()?
Evaluation ships the labeled training set, and a client resumed from a context id has never
seen it. The call raises RuntimeError("call fit() before predict()").
Such a client also has no classes_ until predict_proba runs.
Quota and retries
Why did I get quota_exceeded when I have quota left?
Quota is reserved when a job is submitted and released when it completes, so a burst of
concurrent submits can exhaust the daily allowance before any of them run.
- A job that never leaves the queue holds its reservation for the rest of the UTC day.
- The daily quota counts input rows only, and resets at 00:00 UTC. Output rows bill but do not consume it.
Why does retrying my 429 never succeed?
quota_exceeded is a 429 with retryable: false. Only four codes are retryable, and at 429
only rate_limited is one of them.
- Branch on
retryable, not on the status code. - The SDK has no backoff-retry layer of its own.
Why was my upload rejected only after a long wait?
The SDK serializes and gzips the whole payload locally, then asks the control plane to presign the upload. The size check happens at that point, sopayload_too_large arrives
after the compression pass — no bytes are sent to storage.
Jobs that fail or vanish
Why did my job fail with no error detail?
Uploads are content-addressed, so two byte-identical payloads share one stored object. The first job to finish schedules that object for deletion, and a second job still queued against it fails. The worker logsstaged object missing, the job ends with no error envelope, and the SDK
raises internal_error. Submit both calls with the same idempotency_key so the second
replays the first job rather than queueing a second against the same object.
Why is my result a 404 an hour after it succeeded?
Scored predictions and evaluation metrics are kept for 1 hour, then deleted. The job stays in the ledger; only the result is gone, reported astraining_ref_expired (404).
Collect results from long-lived handles inside the hour, or re-run the job.
Why did I get worker_unavailable?
It is a retryable 503, returned when no worker could accept the job. The SDK also raises it
itself when it cannot reach the API or object storage.
- Inside a poll loop it is absorbed.
predict,evaluateandforecastkeep waiting; afitwait does so only when you passon_warming=. - On the submitting call it reaches you. Retry the call unchanged.
worker_warming_up is in the error contract but nothing emits it, so a cold worker arrives as
worker_unavailable.
Why did my job fail with worker_oom?
The dataset fit the published limits but not the GPU memory available to it. This is a
terminal 500 and is not retried. Reduce rows or columns and resubmit.
What should I quote when I ask for help?
TherequestId. Every typed error envelope carries one, req_ plus 16 hex characters, and
the API logs the same id server-side against the failing request.
invalid_json or invalid_request response carries no id, and an
error the SDK raised before any request has request_id set to None.
Working directly against the REST API
Why does GET /v1/predictions/{id}/result return 404 while the job is running?
The result resource does not exist until the job succeeds, and a request for it before then
returns job_not_found — not a 409 or a 425. Poll GET /v1/predictions/{id} for status, and
read /result once the status is succeeded.
Why did my request return invalid_request with no code?
A body that matches no accepted shape returns a bare {"error":"invalid_request"} — no
code, no category, no requestId. POST /v1/predictions accepts two shapes, and a typo
in the inline one falls through to the context-backed parser, so the response does not say
which shape failed.
Check trainRowCount and outputRowCount first; they are the fields that separate the two.
Forecasting
Why does my forecast fail with schema_mismatch?
The worker requires the set of non-timestamp/target/item_id keys in your context rows to
equal the declared covariateColumns exactly. The SDK derives that set from your context
frame, so this normally comes from submitting forecasts over REST.
A future frame missing a covariate is caught client-side as a ValueError before anything
is uploaded.
Next
- Errors — all 26 codes, their categories and which are retryable
- Limits and quotas — every ceiling and the error you get at it
- The fitted context — expiry, resuming, and skipping it by accident
- Changelog — how versions work and what is guaranteed