Skip to content

fix(ledger): fail import on logs longer than 64 KB - #191

Merged
ariel-formance merged 2 commits into
mainfrom
fix/ledger-import-long-lines
Oct 1, 2026
Merged

ariel-formance merged 2 commits into
mainfrom
fix/ledger-import-long-lines

Conversation

@ariel-formance

@ariel-formance ariel-formance commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

fctl ledger import read the file with bufio.Scanner, which stops on any line longer than its 64 KB default. The scanner error was only checked inside the loop, where it is always nil, so a long log ended the import silently: the logs read so far were sent and the command printed "Ledger imported!".

  • Read lines with bufio.Reader.ReadBytes('\n'), which has no length limit, in both the import loop and openFileWithOffset (--resume-from-last-log).
  • Batching moved into an importLogs helper so read and ImportLogs errors are returned and it can be unit tested.
  • Progress and resume offsets now count the bytes actually read. The old +1 per line was wrong for CRLF files and for a final line with no newline.
  • Behavior change: with --resume-from-last-log, if the ledger's last log ID isn't in the file, the command now fails with log <id> not found in <file>. Before, it jumped to the end of the file, imported nothing, and reported success.

The server side (internal/api/v2/controllers_logs_import.go in ledger) decodes the body with json.NewDecoder, so it has no line limit.

Docs

Phase 1 of RFC 0004 for this repo: fctl had no ./docs, so this PR adds docs/README.md and docs/ledger-import.md (input format, batching, partial imports, resume, and the new missing-ID error with a Migration note). The docs were AI-drafted from the code and need maintainer review.

Test plan

  • New cmd/ledger/import_test.go: a 200 KB log, a final line with no newline, ImportLogs errors returned, resume offset with found and missing IDs
  • go test ./cmd/ledger/, go vet, golangci-lint run ./cmd/ledger/... (0 issues), go build ./...
  • Not run end to end against a live stack

bufio.Scanner stops at lines over its 64 KB default token size, and the
error was only checked inside the loop, where it is always nil. The
import stopped silently and still printed "Ledger imported!".

Read lines with bufio.Reader.ReadBytes, which has no length limit, in
both the import loop and the resume offset lookup. Resume offsets now
count actual bytes, and a resume whose last log ID is not in the file
fails instead of importing nothing.

Confidence: high
Scope-risk: narrow
@ariel-formance
ariel-formance requested a review from a team as a code owner October 1, 2026 13:08
Comment thread cmd/ledger/import.go
@NumaryBot NumaryBot added risk: high bot-reviewed review-inconclusive NumaryBot could not prove that the review gate is satisfied. labels Oct 1, 2026
Bootstrap ./docs (RFC 0004) with a page for fctl ledger import: input
format, batching, partial-import behavior, and the new error when
--resume-from-last-log cannot find the ledger's last log ID in the file.
@NumaryBot NumaryBot added risk: high bot-reviewed review-approved The NumaryBot review gate is satisfied for the current head. and removed risk: high bot-reviewed review-inconclusive NumaryBot could not prove that the review gate is satisfied. labels Oct 1, 2026

@NumaryBot NumaryBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The required automated review completed with no remaining findings.

@ariel-formance
ariel-formance merged commit be85925 into main Oct 1, 2026
7 of 9 checks passed
@ariel-formance
ariel-formance deleted the fix/ledger-import-long-lines branch October 1, 2026 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot-reviewed review-approved The NumaryBot review gate is satisfied for the current head. risk: high

Development

Successfully merging this pull request may close these issues.

2 participants