You used a FFI attribute that can't be used with @send

Hi all,

I received the following error:

You used a FFI attribute that can't be used with @send

FAILED: cannot make progress due to previous errors.
>>>> Finish compiling(exit: 1)

After I tried to create a method function for addEvent like this:

type track
type event
module MidiWriter = {
    @module("midi-writer-js") @new external track: unit => track = "Track"
    @module("midi-writer-js") @send external addEvent: (track, event) => unit = "addEvent"

I have no clue how to fix this error, any ideas?

You don’t need the @module attribute on the @send binding, as the addEvent isn’t imported but held in your object of type track

1 Like


You can’t mix @module with new @send. First you need to factor out the new binding into your own external, which is then used together with your @send bindings.

Here is a full port of the midi-writer-js README example:

// MidiWriter.res

module Event = {
  type t

  @new @module("midi-writer-js")
  external programChangeEvent: {"instrument": int} => t = "ProgramChangeEvent"

  @new @module("midi-writer-js")
  external noteEvent: ({"pitch": array<string>, "duration": string}) => t = "NoteEvent"

module Track = {
  type t
  @module("midi-writer-js") @new external make: unit => t = "Track"
  @send external addEvent: (t, Event.t) => unit = "addEvent"

module Writer = {
  type t
  @module("midi-writer-js") @new external make: (Track.t) => t = "default"

  @send external dataUri: t => string = "dataUri"

let _ = {
  let track = Track.make()

  let change = Event.programChangeEvent({"instrument": 1})

  let note = Event.noteEvent({"pitch": ["C4", "D4", "E4"], "duration": "4"})

  let write = Writer.make(track)

Playground Link

Hope that helps getting the point across!

1 Like

Is this correct? :thinking: Maybe you meant mixing @module and @send?

BTW, maybe a more precise error message could help? I can create an issue, but where? The syntax repo or the compiler repo?

Oops, thanks for that… edited my post.

This should be reported on the compiler repo


Amazing, thank you.
It’s a conceptual challenge to master this.

I only had to change the line
@module("midi-writer-js") @new external make: (Track.t) => t = "default"
@module("midi-writer-js") @new external make: (Track.t) => t = "Writer"

What’s most amazing is that the generated javascript looks exactly as the original from the README example, except for the added exports and indentation.


@ryyppy old post so dont know if the api has changed. Just tried running this and got

var write = new MidiWriterJs(track);
TypeError: MidiWriterJs is not a constructor;

We should post a working version for others who might come through looking for binding examples. I will do so if you or @ronen dont do it first.