Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Schema.isStringFinite (and Number string matching) takes quadratic time on long digit runs

Closed
#9,595 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@magoz is already working on this.

Since Oct 20, 2026.

  • #9596 by @magoz — open

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
66/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
backend

Research direction

The report identifies FINITE_PATTERN and the affected paths: Schema.isStringFinite(), number decoding, record keys, and template literals. Start by searching the schema implementation and tests for FINITE_PATTERN and the number string matching variants, then run the relevant tests with the reported long digit runs. Done when invalid inputs are rejected in linear time across the listed paths and existing number parsing behavior still passes.

Written by the indexing model from the issue text.

Description

What version of Effect is running?

Current main (bbedfc71c0)

What steps can reproduce the bug?
import { Schema } from "effect"

const is = Schema.is(Schema.String.check(Schema.isStringFinite()))

for (const n of [5_000, 10_000, 20_000, 40_000]) {
  const input = "1".repeat(n) + "x"
  const start = performance.now()
  is(input) // false
  console.log(n, Math.round(performance.now() - start), "ms")
}
What is the expected behavior?

Rejecting the string takes time linear in its length (a few ms at 40k chars).

What do you see instead?

Quadratic time (Node v24.21.0): 12 ms, 47 ms, 163 ms, 751 ms. Each doubling of n makes it ~4× slower; 80k chars take ~2.8 s.

Additional information

The bare regex shows the same times, so the problem is FINITE_PATTERN ([+-]?\d*\.?\d+(?:[Ee][+-]?\d+)?): for a run of digits not followed by a valid ending, \d* and \d+ retry every split of the run.

/^[+-]?\d*\.?\d+(?:[Ee][+-]?\d+)?$/.test("1".repeat(40_000) + "x") // ~700 ms

The same regex (or its Infinity|-Infinity|NaN variant) runs in other places. Each was ~4× slower per doubling up to 40k chars:

Path 40k chars
Schema.isStringFinite() 729 ms
Schema.toCodecStringTree(Schema.Struct({ n: Schema.Number })) decoding { n: input } 640 ms
Schema.Record(Schema.Number, Schema.String) decoding { [input]: "v" } 491 ms
Schema.TemplateLiteral(["a", Schema.Number]) checking "a" + input 717 ms

Inputs that trigger it: "1".repeat(n) followed by "x", ".", "e" or ".1x", and the same with a leading -. "." + "1".repeat(n) + "x" and "1e" + "1".repeat(n) + "x" stay fast. Valid digit runs are fast too. Schema.NumberFromString does not use the regex and is not affected.

Dominant language
TypeScript
Stars
16.7k
Forks
808
Avg merge
10h 7m
Merged PRs (30d)
808

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Effect-TS/effect

All issues in Effect-TS/effect

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.