clojurescript

Pepijn de Vos 2025-09-01T10:40:52.000659Z

I've stumbled across the wildest advanced compilation bug yet: (debug here is essentially #(println (js->clj %) )

debug({"m":"1"})
{m 1}
null
debug({"mo":"1"})
{mo 1}
null
debug({"mo":"10"})
{mo 10}
null
debug({"j":"10"})
{j 10}
null 
debug({"m":"10"})
Uncaught Error: [object Object] is not ISeqable

Pepijn de Vos 2025-09-01T10:44:11.272069Z

It is like... specifically the m key with a value that is a multi-digit number as a string.

p-himik 2025-09-01T10:44:22.925739Z

Do you call debug in a JS console? So it's an exported CLJS function?

Pepijn de Vos 2025-09-01T10:44:42.914939Z

Yeah, it only happens in a release build

p-himik 2025-09-01T10:44:54.856909Z

Would you be able to create an MRE?

Pepijn de Vos 2025-09-01T10:45:50.010309Z

Well I suspect it is dependent on some code specifically getting renamed to m in advanced compilation

Pepijn de Vos 2025-09-01T10:48:33.986409Z

like, if I compile with release --debug it doesn't happen, and that only seems to turn off :pseudo-names > :pretty-print and :pseudo-names default to false. You can use shadow-cljs release app --debug to enable both temporarily without touching your config. This is very useful when running into problem with release builds

p-himik 2025-09-01T10:51:30.775659Z

That hypothesis makes sense but it would still be helpful to have a clean reproduction case. :)

Pepijn de Vos 2025-09-01T10:52:51.076979Z

Yea, I just don't have any clue how I'd do that

Pepijn de Vos 2025-09-01T10:54:24.702139Z

okay I have... one idea... stand by

Pepijn de Vos 2025-09-01T11:15:50.654239Z

Yeah I made a clean project trying to do every letter of the alphabet and nothing errors

Pepijn de Vos 2025-09-01T11:16:41.471399Z

My hypothesis was that the code would be compiled to SOME letter and i'd just try them all

Pepijn de Vos 2025-09-01T11:21:01.388439Z

got it!!!

Pepijn de Vos 2025-09-01T11:24:23.426459Z

SES Removing unpermitted intrinsics lockdown-install.js:1:203117
  Removing intrinsics.%DatePrototype%.toTemporalInstant lockdown-install.js:1:202962
GET

[HTTP/1 404 File not found 1ms]

Testing js->clj with compacted identifiers: editor.js:4:480
Key: a editor.js:4:480
{a 100} editor.js:4:480
Key: b editor.js:4:480
{b 100} editor.js:4:480
Key: c editor.js:4:480
{c 100} editor.js:4:480
Key: d editor.js:4:480
[snip]
Key: A editor.js:4:480
{A 100} editor.js:4:480
Key: B editor.js:4:480
{B 100} editor.js:4:480
Key: C editor.js:4:480
{C 100} editor.js:4:480
Key: D editor.js:4:480
SES_UNCAUGHT_EXCEPTION: Error: [object Object] is not ISeqable
    I 
    B 
    tc 
    U 
    I 
    ge 
    h 
    Z 
    Ee 
    <anonymous> 
lockdown-install.js:1:145467
GET

[HTTP/1 404 File not found 0ms]

Pepijn de Vos 2025-09-01T11:24:53.241119Z

@p-himik reproducer:

(ns nyancad.mosaic.editor)

(defn generate-compacted-identifier 
  "Generate compacted identifier: a-z, A-Z, aa-az, ba-bz, etc."
  [n]
  (let [chars "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        char-count (count chars)]
    (if (< n char-count)
      (str (nth chars n))
      (let [prefix-idx (quot (- n char-count) char-count)
            suffix-idx (rem (- n char-count) char-count)]
        (str (generate-compacted-identifier prefix-idx)
             (nth chars suffix-idx))))))

(defn create-js-object-with-key 
  "Create a JS object with the given key and value '100'"
  [key-str]
  (let [obj (js-obj)]
    (aset obj key-str "100")
    obj))

(defn ^:export init []
  (println "Testing js->clj with compacted identifiers:")
  (dotimes [i 60]
    (let [key (generate-compacted-identifier i)
          js-obj (create-js-object-with-key key)]
      (println (str "Key: " key))
      (println (js->clj js-obj)))))

p-himik 2025-09-01T11:33:43.203349Z

Thanks!

Pepijn de Vos 2025-09-01T11:35:15.098089Z

The shadow-cljs config if it's helpful:

{:source-paths ["src/main"]

 :dev-http {8080 "public"}
 :builds
 {:frontend
  {:target :esm
   :output-dir "public/js"
   :modules {:editor {:init-fn nyancad.mosaic.editor/init}}
   :compiler-options {:output-feature-set :es2018, :source-map true}}
  }}
I can zip up the whole project if you want

p-himik 2025-09-01T11:39:18.615039Z

Probably no need. I think your hypothesis is correct and I was able to reproduce it on my end as well. I mentioned it in #cljs-dev.