Options could not be loaded from API - issue with tag field and options linked to json

,

Hello there,

I’m stumbling onto an error in the panel when trying to edit some pages with a tag field with options linked to a json.

Prod: Kirby 5.4.4, PHP 8.4.16, Apache 2.4.67 on Infomaniak shared webhosting (850MB memory and 120s max limit of exec.)
Local: Kirby 5.4.4, PHP 8.4.20, Apache 2.4.66 (with ddev)

I only see that error on my remote. It appears after roughly 8 seconds trying to load.
On local instance, page editors appears in a sec.

Debug is deactivated on the two instances and cache activated on both.

The json file is online and I can access it.

Here’s the json if you want to have a look.

Here’s the blueprint extract when this option is called:

speakerCountry:
  label: Pays
  type: tags
  width: 1/3
  min: 0
  max: 1
  icon: map
  options: 
    type: api
    url: "{{ site.url }}/assets/data/countries.json"
    text: "{{ item.DisplayName }}"
    value: "{{ item.DisplayName }}"
moderatorCountry:
  label: Pays
  type: tags
  width: 1/3
  min: 0
  max: 1
  icon: map
  options: 
    type: api
    url: "{{ site.url }}/assets/data/countries.json"
    text: "{{ item.DisplayName }}"
    value: "{{ item.DisplayName }}"

Same error happens on Kirby 4.9.4. Behavior is different though, the panel loader spins for a few seconds then stops. It looks like it doesn’t work but finally after a minute or so the page loads. Only the error is located to the field where the issue is happening.


I’ve been trying to find a solution but I couldn’t find any and I’m not sure where to look to find a hint.

Could it be due to a lack of memory? json has only 251 lines, not so big isn’t it?

It looks like it’s treating the full json every time, maybe there’s a way to optimize this?

Any help would be greatly appreciated :folded_hands:

update: I just tried with very small JSON (only 2 lines) and I still have the same error. So it might not be a memory issue. :thinking:

Also tried on Firefox and a clean Chrome last version with no plugins. Same error.

Does your second example only have one field that queries the json file? What is the exact structure of those fields in the first example, are they inside some other field or standalone? The extract from the blueprint is a bit short…

Could you enable debug mode and check if you get any errors in your console? It might be worth checking the php and server error logs as well.

Hi @texnixe thanks for you answer!

The second example is the exact same blueprint and json. Just the kirby version is different (I updated to 5 meanwhile thinking it might help).

Here’s the blueprint:

title: event
icon: 📅
num: "{{ page.from.toDate('Ymd') }}"
image:
    back: white
    color: grey
    
tabs:
  content:
    label: Contenu
    columns:
      main:
        width: 2/3
        sections:
          infos:
            type: fields
            fields:
              titleTranslated:
                label: Titre traduit en anglais
                type: text
                when: 
                  eventIsEnglish: false
              thematics:
                label: Tags
                type: tags
                max: 3
                separator: ;
                help: Lister 1 à 3 thématiques, pas nécessaire de mettre le #
                options:
                  type: query
                  query: page.siblings.pluck("thematics", ";", true)
              from:
                label: Démarrage de l'évement
                type: date
                width: 1/2
                display: DD-MM-YYYY
                time: true
              to:
                label: Fin de l'évenement
                type: date
                width: 1/2
                display: DD-MM-YYYY
                time: true
              speakers:
                label: Intervenant·e·s
                type: structure
                columns:
                  speakerName:
                    width: 3/10
                  speakerpublishers: true
                  speakerAbout: true
                  speakerCountry: true
                  speakerPortrait:
                    width: 1/10
                fields:
                  speakerName:
                    label: Prénom Nom
                    autofocus: true
                    type: text
                    width: 1/3
                    sortable : true
                  speakerpublishers:
                    label: Maison d'édition
                    type: multiselect
                    width: 1/3
                    help: "Pour toute nouvelle maison d'édition, créer sa fiche avant."
                    options:
                      type: query
                      query: site.pages.findBy('autoid', 'publishers').children.listed
                      text: "{{ item.title }}"
                      value: "{{ item.uuid }}"
                  speakerPortrait:
                    label: Portrait
                    empty: Seuls les personnes qui ont un portrait renseigné seront mises en avant
                    type: files
                    uploads: portrait
                    max: 1
                    multiple: false
                    layout: cardlets
                    size: tiny
                    width: 1/3
                  speakerAbout:
                    label: Info additionnelle
                    type: text
                    width: 2/3
                  speakerCountry:
                    label: Pays
                    type: tags
                    width: 1/3
                    min: 0
                    max: 1
                    icon: map
                    options: 
                      type: api
                      url: "{{ site.url }}/assets/data/countries.json"
                      text: "{{ item.DisplayName }}"
                      value: "{{ item.DisplayName }}"
                  speakerBioOriginal:
                    label: Bio originale
                    help: Langue originale de la bio
                    type: textarea
                    size: medium
                    width: 1/2
                    maxlength: 800
                    buttons:
                      - bold
                      - italic
                      - link
                  speakerBioTranslated:
                    label: Bio traduite
                    help: Optionnel, si besoin d'une version traduite
                    type: textarea
                    size: medium
                    maxlength: 800
                    width: 1/2
                    buttons:
                      - bold
                      - italic
                      - link

              moderators:
                label: Modérateur·ice·s
                type: structure
                columns:
                  moderatorName:
                    width: 3/10
                  moderatorpublishers: true
                  moderatorAbout: true
                  moderatorCountry: true
                  moderatorPortrait:
                    width: 1/10
                fields:
                  moderatorName:
                    label: Prénom Nom
                    autofocus: true
                    type: text
                    width: 1/3
                  moderatorpublishers:
                    label: Maison d'édition
                    type: multiselect
                    width: 1/3
                    help: 'Si vous ne trouvez pas la maison d'édition que vous cherchez, n'oubliez pas de commencer par créer sa fiche.'
                    options:
                      type: query
                      query: site.pages.findBy('autoid', 'publishers').children.listed
                      text: "{{ item.title }}"
                      value: "{{ item.uuid }}"
                  moderatorPortrait:
                    label: Portrait
                    empty: Seuls les personnes qui ont un portrait renseigné seront mises en avant
                    type: files
                    uploads: portrait
                    max: 1
                    multiple: false
                    layout: cardlets
                    size: tiny
                    width: 1/3
                  moderatorAbout:
                    label: Info additionnelle
                    type: text
                    width: 2/3
                  moderatorCountry:
                    label: Pays
                    type: tags
                    width: 1/3
                    min: 0
                    max: 1
                    icon: map
                    options: 
                      type: api
                      url: "{{ site.url }}/assets/data/countries.json"
                      text: "{{ item.DisplayName }}"
                      value: "{{ item.DisplayName }}"
                  moderatorBioOriginal:
                    label: Bio originale
                    help: Langue originale de la bio
                    type: textarea
                    size: medium
                    width: 1/2
                    maxlength: 800
                    buttons:
                      - bold
                      - italic
                      - link
                  moderatorBioTranslated:
                    label: Bio traduite
                    help: Optionnel, si besoin d'une version traduite
                    type: textarea
                    size: medium
                    maxlength: 800
                    width: 1/2
                    buttons:
                      - bold
                      - italic
                      - link
              description:
                label: Description
                type: textarea
                size: medium
                buttons:
                  - bold
                  - italic
                  - '|'
                  - link
                  - '|'
                  - ul
                  - ol
              descriptionTranslated:
                label: Description traduite en anglais
                type: textarea
                buttons:
                  - bold
                  - italic
                  - '|'
                  - link
                  - '|'
                  - ul
                  - ol
                size: medium
                when:
                  eventIsEnglish: false

      aside:
        width: 1/3
        sections:
          side:
            type: fields
            fields:
              eventIsEnglish:
                label: Est-ce un événement originalement en anglais ?
                type: toggle
                text:
                  - "Non"
                  - "Oui"
                default: "Non"
              eventFormat:
                label: "Format d'évenement"
                type: multiselect
                max: 1
                options:
                  - Reading
                  - Rights Market
                  - Talk
                  - Workshop
                  - Concert
                required: true
              language:
                label: "Langue de l'évenement"
                type: tags
                icon: smile
                max: 1
                options:
                  type: api
                  url: "{{ site.url }}/assets/data/languages.json"
                  text: "{{ item.name }}"
                  value: "{{ item.name }}"
              transcription:
                label: Langue·s interprétariat
                type: tags
                icon: globe
                options:
                  type: api
                  url: "{{ site.url }}/assets/data/languages.json"
                  text: "{{ item.name }}"
                  value: "{{ item.name }}"
              location:
                label: Lien pour participer en ligne
                type: url
                help: "Le bouton pour rejoindre s'affichera une fois le lien renseigné."
              replay:
                label: Lien du replay
                type: embed
                help: "Insérer le lien youtube de l'enregistrement."
              organizer:
                label: Structure organisatrice
                type: text
                default: Alliance des Editeurs
                placeholder: Alliance des Editeurs
                help: Renseigner dans le cas où ce serait une autre structure
  meta: tabs/meta/page

I get a similar error also with this one:

title: book
icon: book
image:
    back: white
    color: grey

tabs:
  content:
    label: Contenu
    columns:

      main:
        width: 2/3
        sections:
          by:
            type: fields
            fields:
              

              titleTranslated:
                label: Titre traduit en anglais
                type: text
                when: 
                  bookIsEnglish: false

              authors:
                label: Auteur·ice·s et/ou Illustrateur·ice·s
                type: structure
                fields:
                  authorName:
                    label: Prénom Nom
                    autofocus: true
                    type: text
                    width: 1/2
                  authorTranslated:
                    label: Traduction en anglais
                    help: 'optionnel, utile pour les auteur·ice·s dont le nom est écrit dans une langue non-latine'
                    type: text
                    width: 1/2
                  authorIsIllustrator:
                    label: Est-ce un·e illustrateur·ice ?
                    type: toggle
                    width: 1/2
                    text:
                      - "Non"
                      - "Oui"
                    default: "Non"

              bookIsTranslated:
                label: Ce livre est-il une traduction ?
                type: toggle
                width: 1/3
                text:
                  - "Non"
                  - "Oui"
                default: "Non"

              originalLang:
                label: Langue originale
                type: tags
                icon: globe
                width: 1/3
                options:
                  type: api
                  url: "{{ site.url }}/assets/data/languages.json"
                  text: "{{ item.name }}"
                  value: "{{ item.name }}"
                when:
                  bookIsTranslated: true
              translator:
                label: Traducteur·ice
                type: text
                icon: user
                width: 1/3
                when:
                  bookIsTranslated: true

              description:
                label: Résumé
                type: textarea
                buttons:
                  - bold
                  - italic
                  - '|'
                  - link
                  - '|'
                  - ul
                  - ol
                size: medium

              descriptionTranslated:
                label: Résumé traduit en anglais
                type: textarea
                buttons:
                  - bold
                  - italic
                  - '|'
                  - link
                  - '|'
                  - ul
                  - ol
                size: medium
                when:
                  bookIsEnglish: false

              introAuthor:
                label: Présentation de·s l'auteur·ice·s
                type: textarea
                buttons:
                  - bold
                  - italic
                  - '|'
                  - link
                  - '|'
                  - ul
                  - ol
                size: small

              introAuthorTranslated:
                label: Présentation de·s l'auteur·ice·s, traduite en anglais
                type: textarea
                buttons:
                  - bold
                  - italic
                  - '|'
                  - link
                  - '|'
                  - ul
                  - ol
                size: small
                when:
                  bookIsEnglish: false

              genre:
                label: "Genre littéraire"
                type: multiselect
                width: 1/2
                max: 1
                options:
                  - Literature 
                  - Human and social sciences
                  - Children's literature
                  - Illustrated books
                  - Graphic novel

              publishDate:
                label: "Année de publication"
                type: date
                width: 1/4
                display: YYYY

              isbn:
                label: "ISBN"
                type: text
                width: 1/4

              price:
                label: "Prix"
                type: number
                width: 1/4

              currency:
                label: "Devise"
                type: multiselect
                width: 1/4
                max: 1
                options:
                  type: api
                  url: "{{ site.url }}/assets/data/currencies.json"
                  text: "{{ item.name }}"
                  value: "{{ item.symbol }}"

              cta:
                label: Lien pour se procurer le livre
                type: url
                width: 1/2

              rights:
                label: Droits en vente
                type: list
                marks:
                  - bold
                  - italic
                  - '|'
                  - link

              awards:
                label: Récompenses et distinctions
                type: list
                marks:
                  - bold
                  - italic
                  - '|'
                  - link

      sidebar:
        width: 1/3
        sections:

          isEnglish:
            type: fields
            fields:
              bookIsEnglish:
                label: Est-ce un livre publié en anglais ?
                type: toggle
                text:
                  - "Non"
                  - "Oui"
                default: "Non"
          
          fair:
            type: fields
            fields:
              fairYear:
                label: Année de présentation en festival
                type: select
                options:
                  type: query
                  query: site.fairinfos.toStructure
                  text: "Édition {{ item.year }}"
                  value: "{{item.year}}"
                disabled: false
                required: true

          publisher:
            type: fields
            fields:
              publishers:
                label: Maison(s) d'édition
                type: multiselect
                help: 'Si vous ne trouvez pas la maison d'édition que vous cherchez, n'oubliez pas de commencer par créer sa fiche.'
                options:
                  type: query
                  query: site.pages.findBy('autoid', 'publishers').children.listed
                  text: "{{ item.title }}"
                  value: "{{ item.uuid }}"

              publishingLang:
                label: Langue(s) de publication
                type: tags
                icon: globe
                options:
                  type: api
                  url: "{{ site.url }}/assets/data/languages.json"
                  text: "{{ item.name }}"
                  value: "{{ item.name }}"

          cover:
            type: fields
            fields:
              coverFile:
                label: Couverture
                type: files
                multiple: false
                layout: cards
                image:
                  cover: false
                  ratio: 3/4 
              relatedEvents:
                label: Evénement(s) lié(s)
                type: pages
                query: site.pages.findBy('autoid','program').children
                empty: Aucun évenement sélectionné pour le moment

          infos:
            label: Aide
            type: info
            theme: none
            text: Renseignez dans cette fiche les informations concernant le livre présenté et téléversez sa couverture.
  meta: tabs/meta/page

Ok, thanks for providing this additional info. Could you test if you run into the same issue if you use those json fields for tags fields that are not within a structure field (or any other nested field).

Just retried with this:

title: event
icon: 📅
num: "{{ page.from.toDate('Ymd') }}"
image:
    back: white
    color: grey
    
tabs:
  content:
    label: Contenu
    columns:
      main:
        width: 2/3
        sections:
          infos:
            type: fields
            fields:
              titleTranslated:
                label: Titre traduit en anglais
                type: text
                when: 
                  eventIsEnglish: false
              eventCountry:
                label: Pays
                type: tags
                width: 1/3
                min: 0
                max: 1
                icon: map
                options: 
                  type: api
                  url: "{{ site.url }}/assets/data/countries.json"
                  text: "{{ item.DisplayName }}"
                  value: "{{ item.DisplayName }}"
              thematics:
                label: Tags
                type: tags
                max: 3
                separator: ;
                help: Lister 1 à 3 thématiques, pas nécessaire de mettre le #
                options:
                  type: query
                  query: page.siblings.pluck("thematics", ";", true)
              from:
                label: Démarrage de l'évement
                type: date
                width: 1/2
                display: DD-MM-YYYY
                time: true
              to:
                label: Fin de l'évenement
                type: date
                width: 1/2
                display: DD-MM-YYYY
                time: true
              speakers:
                label: Intervenant·e·s
                type: structure
                columns:
                  speakerName:
                    width: 3/10
                  speakerpublishers: true
                  speakerAbout: true
                  speakerCountry: true
                  speakerPortrait:
                    width: 1/10
                fields:
                  speakerName:
                    label: Prénom Nom
                    autofocus: true
                    type: text
                    width: 1/3
                    sortable : true
                  speakerpublishers:
                    label: Maison d'édition
                    type: multiselect
                    width: 1/3
                    help: "Pour toute nouvelle maison d'édition, créer sa fiche avant."
                    options:
                      type: query
                      query: site.pages.findBy('autoid', 'publishers').children.listed
                      text: "{{ item.title }}"
                      value: "{{ item.uuid }}"
                  speakerPortrait:
                    label: Portrait
                    empty: Seuls les personnes qui ont un portrait renseigné seront mises en avant
                    type: files
                    uploads: portrait
                    max: 1
                    multiple: false
                    layout: cardlets
                    size: tiny
                    width: 1/3
                  speakerAbout:
                    label: Info additionnelle
                    type: text
                    width: 2/3
                  speakerBioOriginal:
                    label: Bio originale
                    help: Langue originale de la bio
                    type: textarea
                    size: medium
                    width: 1/2
                    maxlength: 800
                    buttons:
                      - bold
                      - italic
                      - link
                  speakerBioTranslated:
                    label: Bio traduite
                    help: Optionnel, si besoin d'une version traduite
                    type: textarea
                    size: medium
                    maxlength: 800
                    width: 1/2
                    buttons:
                      - bold
                      - italic
                      - link

              moderators:
                label: Modérateur·ice·s
                type: structure
                columns:
                  moderatorName:
                    width: 3/10
                  moderatorpublishers: true
                  moderatorAbout: true
                  moderatorCountry: true
                  moderatorPortrait:
                    width: 1/10
                fields:
                  moderatorName:
                    label: Prénom Nom
                    autofocus: true
                    type: text
                    width: 1/3
                  moderatorpublishers:
                    label: Maison d'édition
                    type: multiselect
                    width: 1/3
                    help: 'Si vous ne trouvez pas la maison d'édition que vous cherchez, n'oubliez pas de commencer par créer sa fiche.'
                    options:
                      type: query
                      query: site.pages.findBy('autoid', 'publishers').children.listed
                      text: "{{ item.title }}"
                      value: "{{ item.uuid }}"
                  moderatorPortrait:
                    label: Portrait
                    empty: Seuls les personnes qui ont un portrait renseigné seront mises en avant
                    type: files
                    uploads: portrait
                    max: 1
                    multiple: false
                    layout: cardlets
                    size: tiny
                    width: 1/3
                  moderatorAbout:
                    label: Info additionnelle
                    type: text
                    width: 2/3
                  moderatorBioOriginal:
                    label: Bio originale
                    help: Langue originale de la bio
                    type: textarea
                    size: medium
                    width: 1/2
                    maxlength: 800
                    buttons:
                      - bold
                      - italic
                      - link
                  moderatorBioTranslated:
                    label: Bio traduite
                    help: Optionnel, si besoin d'une version traduite
                    type: textarea
                    size: medium
                    maxlength: 800
                    width: 1/2
                    buttons:
                      - bold
                      - italic
                      - link
              description:
                label: Description
                type: textarea
                size: medium
                buttons:
                  - bold
                  - italic
                  - '|'
                  - link
                  - '|'
                  - ul
                  - ol
              descriptionTranslated:
                label: Description traduite en anglais
                type: textarea
                buttons:
                  - bold
                  - italic
                  - '|'
                  - link
                  - '|'
                  - ul
                  - ol
                size: medium
                when:
                  eventIsEnglish: false

      aside:
        width: 1/3
        sections:
          side:
            type: fields
            fields:
              eventIsEnglish:
                label: Est-ce un événement originalement en anglais ?
                type: toggle
                text:
                  - "Non"
                  - "Oui"
                default: "Non"
              eventFormat:
                label: "Format d'évenement"
                type: multiselect
                max: 1
                options:
                  - Reading
                  - Rights Market
                  - Talk
                  - Workshop
                  - Concert
                required: true
              language:
                label: "Langue de l'évenement"
                type: tags
                icon: smile
                max: 1
                options:
                  type: api
                  url: "{{ site.url }}/assets/data/languages.json"
                  text: "{{ item.name }}"
                  value: "{{ item.name }}"
              transcription:
                label: Langue·s interprétariat
                type: tags
                icon: globe
                options:
                  type: api
                  url: "{{ site.url }}/assets/data/languages.json"
                  text: "{{ item.name }}"
                  value: "{{ item.name }}"
              location:
                label: Lien pour participer en ligne
                type: url
                help: "Le bouton pour rejoindre s'affichera une fois le lien renseigné."
              replay:
                label: Lien du replay
                type: embed
                help: "Insérer le lien youtube de l'enregistrement."
              organizer:
                label: Structure organisatrice
                type: text
                default: Alliance des Editeurs
                placeholder: Alliance des Editeurs
                help: Renseigner dans le cas où ce serait une autre structure
  meta: tabs/meta/page

Still same issue. Working fine on local instance but not on remote instance. :confused:

Did you check debug mode/console, error logs?

When I activate debug mode there nothing more on the front. Same error popup.

Here’s what I see in the browser console:

Error: The request to https://staging-babelica.pcfh.studio/panel/pages/program+faire-entendre-les-voix-dominees failed
zc Babelica
Vc Babelica
Uc Babelica
request Babelica
get Babelica
open Babelica
load Babelica
load Babelica
open Babelica
onClick Babelica
VueJS 33
Caused by: undefined
index.min.js:2:421582

And in the remote server console, I see these kind… which are not related I believe ?

staging.xxx [Tue Jun 30 22:43:33.258491 2026] [proxy_fcgi:error] [pid 3114554:tid 140194955118336] [client 193.32.126.228:0] AH01071: Got error 'PHP message: Whoops\\Exception\\ErrorException: imagecreatefromstring(): gd-png: libpng warning: iCCP: known incorrect sRGB profile in /home/clients/xxxx/vendor/claviska/simpleimage/src/claviska/SimpleImage.php:261\nStack trace:\n#0 [internal function]: Whoops\\Run->handleError(2, 'imagecreatefrom...', '/home/clients/5...', 261)\n#1 /home/clients/xxx/vendor/claviska/simpleimage/src/claviska/SimpleImage.php(261): imagecreatefromstring('\\x89PNG\\r\\n\\x1A\\n\\x00\\x00\\x00\\rIHD...')\n#2 /home/clients/xxx/vendor/claviska/simpleimage/src/claviska/SimpleImage.php(233): claviska\\SimpleImage->fromString('\\x89PNG\\r\\n\\x1A\\n\\x00\\x00\\x00\\rIHD...')\n#3 /home/xxx/kirby/src/Image/Darkroom/GdLib.php(30): claviska\\SimpleIm...', referer ``https://xxx/panel/site

I‘d test with a single field to check if it works at all, not such a complex blueprint with multiple queries

Here’s what I tested with a very simple blueprint as you suggested :

title: test

sections:
  content:
    type: fields
    fields:
      speakerCountry:
        label: Pays
        type: tags
        icon: map
        min: 0
        max: 1
        options: 
          type: api
          url: "{{ site.url }}/assets/data/countries.json"
          text: "{{ item.DisplayName }}"
          value: "{{ item.DisplayName }}"
      speakerLanguage:
        label: "Langue de l'évenement"
        type: tags
        icon: smile
        max: 1
        options:
          type: api
          url: "{{ site.url }}/assets/data/languages.json"
          text: "{{ item.name }}"
          value: "{{ item.name }}"

And unfortunately I’m still getting the same error on the remote production server :cry:

I’ve also tried to put the full URL for the json and same behavior.

If I try to put a wrong URL, I get the same error on both side: ok.

I wonder if there’s something on the remote server which preventing kirby’s php from accessing the json? :thinking: I don’t know if this is related but I tried to enable `Allow_url_fopen` but still same error.

Is there another way I could try to store that data so we may not need to access a json file? By converting it into an array maybe, but can my options fields point to an array?

Ok I found the source of the problem : it’s infomaniak which is blocking somehow the access to the json.

I tried to host the json files on another hosting, simple bucket direct access. And it works.

Somehow, the access to the file from a remote server (ironically hosted on their own platform) is forbidden. I’m going to write to them and meanwhile host the json elsewhere.

Thanks for your help @texnixe !