HarperFast / HarperFast/harper

?select($expiresAt) on a non-caching @table → 500 null-deref

Open
#1,437 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
89
Forks
10
Avg merge
2d 6h
Merged PRs (30d)
200

Description

## Summary

`GET /T/?select($expiresAt,...)` (or a collection select of `$expiresAt`) on a plain (non-caching) `@table(expiration: N)` resource crashes with a 500:

```
TypeError: Cannot read properties of undefined (reading 'expiresAt')
```

The `$expiresAt` virtual resolver assumes a caching-context shape that a non-caching table lacks. There is no REST-queryable way to read a record's remaining per-record TTL on an ordinary table — you can SET `expiresAt` via the ops API but cannot read it back via `select`.

**Severity: Low** — observability/introspection gap plus an unhandled-error-as-500 (another instance of the handled-error-as-500 pattern). No data impact.

## Context

The core per-record-TTL feature is otherwise correct: priority over the table default, selective multi-worker eviction, reset-on-update, and lazy-expiry-on-read for past/0 timestamps all behave as expected. This is specifically the `$expiresAt`-via-REST-select read path on a non-caching table.

## Suggested fix

Make `$expiresAt` resolve (returning the record's expiration) — or cleanly omit it — on non-caching tables, instead of throwing.

---
*Found via exploratory QA (scenario QA-208) against `7aaa5a152` on a feature branch; expected to reproduce on `main`. Filed by Claude (Opus 4.8) on Kris's go-ahead.*

Contributor guide

Open the contributing guide

Research direction

Reproduce QA-208 with a REST select of $expiresAt on a non-caching @table, then trace the $expiresAt virtual resolver used by the GET and collection-select paths. Done means the request no longer returns a null-dereference 500 and either returns the record expiration or cleanly omits the field.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
api, database
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.