Skip to content

[BUG] Configuration Map keys containing dots silently fail to expand in connector fields (Velocity property navigation #417

Open

Description

@djkene70

Describe the bug
A Configuration Map key that contains dots — for example db.warehouse.url — is not
expanded when referenced as ${db.warehouse.url} in a connector field such as a Database
Reader/Writer URL, username or password. The raw ${...} text is passed through to the
connector, which then fails with an error that points at the connector rather than at the
key name.

Keys with no dots expand correctly in the same fields.

Consistently reproducible: yes, on every deploy, on both Database Reader and Database
Writer, in url, username and password.

The underlying cause is that connector fields are resolved with Velocity, where ${a.b.c}
means "object a, property b, property c" rather than a lookup of a flat key named
a.b.c. The Configuration Map is loaded into the Velocity context as a flat map
(TemplateValueReplacer.getDefaultContext() calls
loadContextFromMap(context, ConfigurationController.getInstance().getConfigurationMap())),
so a dotted key exists in the map but is unreachable through dotted reference syntax.
Velocity leaves an unresolvable reference untouched, which is why the literal is passed on.

I am not arguing Velocity should behave differently. The problem is that this fails with
no warning anywhere, and the resulting error misdirects.

To Reproduce

  1. Settings -> Configuration Map, add a key with dots:
    test.cfgmap.url = jdbc:postgresql://host.example.org:5432/db
  2. Create a channel with a Database Reader source.
  3. Set the Reader's URL to ${test.cfgmap.url}, driver org.postgresql.Driver,
    select statement SELECT 1.

Steps to reproduce the behavior:

  1. Deploy the channel.
  2. Look at the server log.
  3. See the deploy fail with the unexpanded literal.

Expected behavior
${test.cfgmap.url} resolves to the Configuration Map value, the same way a key without
dots does — or, failing that, some indication that the reference could not be resolved.

Actual behavior
The literal ${test.cfgmap.url} is handed to the connector:

Caused by: com.mirth.connect.donkey.server.ConnectorTaskException: Failed to initialize database connection
	at com.mirth.connect.connectors.jdbc.DatabaseReceiverQuery.initConnection(DatabaseReceiverQuery.java:124)
	at com.mirth.connect.connectors.jdbc.DatabaseReceiverQuery.start(DatabaseReceiverQuery.java:87)
	at com.mirth.connect.connectors.jdbc.DatabaseReceiver.onStart(DatabaseReceiver.java:115)
Caused by: java.sql.SQLException: No suitable driver found for ${test.cfgmap.url}
	at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:706)
	at com.mirth.connect.connectors.jdbc.DatabaseReceiverQuery.initSelectConnection(DatabaseReceiverQuery.java:340)

With a dot-free key (stedi_mode, whose value is P) the same channel produces:

java.sql.SQLException: No suitable driver found for P

which is the expected substitution — P is not a valid JDBC URL, so it fails, but the
value was clearly resolved.

With dot-free keys used for url, username and password throughout, the Database Reader
connects successfully, emits a row, and the Database Writer connects and sends
successfully. So both connectors do expand these fields; only the dots break it.

There is no WARN or ERROR anywhere saying a reference was left unresolved.

Screenshots
N/A — log output above.

Environment (please complete the following information):

  • OS: Windows Server 2025
  • Java Distribution/Version: OpenJDK 17.0.19 (bundled with the OIE installer)
  • Connect Version: Open Integration Engine 4.6.0
  • Database backend: PostgreSQL 17

Behaviour should be platform-independent — Velocity's grammar and Java .properties key
handling are the same everywhere.

Workaround(s)
Yes, and it is easy once you know: do not use dots in Configuration Map keys that will be
referenced from connector fields.
Rename db.warehouse.url to db_warehouse_url and
${db_warehouse_url} resolves correctly.

Note that dotted keys still work fine from JavaScript, because
configurationMap.get('db.warehouse.url') is a literal string lookup rather than a Velocity
template. So the same key works in one place and silently fails in another, which is what
makes this easy to trip over.

Additional context
Dots are a natural convention for namespacing configuration keys and the Configuration Map
UI accepts them without complaint, so this is easy to walk into. I suspect it is the origin
of the fairly widespread belief that Configuration Map values "don't work in connector
URLs" — they do, as long as the key has no dots.

Possible resolutions, cheapest first:

  1. Documentation — note that keys referenced from connector fields must not contain
    dots, and that dotted keys remain usable from JavaScript via configurationMap.get().
    This alone would have saved me the investigation.
  2. UI warning when a key containing a dot is added to the Configuration Map.
  3. Log a warning at deploy time when a connector field still contains an unresolved
    ${...} after replacement.
    This is the one I would find most valuable — it would
    surface the whole class of unresolved-reference mistakes (typos, deleted keys, wrong
    scope), not just dotted keys.

Happy to open a PR for the documentation change, or for option 3 if that is of interest.

Activity

  1. djkene70 commented on Oct 27, 2026

    @djkene70
    Author

    I filed this one and I still have the reproduction, so I would like to take it.

    Plan is to fix the property-navigation path so a Configuration Map key containing dots resolves
    as a literal key instead of being treated as a Velocity property chain, with a unit test.

    On where that test goes: the obvious home is TemplateValueReplacerTests, but having built the
    project, that class never actually runs. The root build.gradle test filter is
    include '**/*Test.class' — singular — and the class is named ...Tests. Forty files match that
    pattern, holding 186 @Test methods between them. Several look parked on purpose (the donkey
    PerformanceTests and DonkeyDaoTests appear to need a live database), so I am not assuming it
    is a bug — but it does mean I will put the new case in a class that already runs rather than add
    one that cannot fail. Happy to open a separate issue about the filter if it is worth a look.

    Flagging the overlap in case anyone sees a conflict: #515 and #520 are both in the Configuration
    Map area, but as far as I can tell they are in the persistence API, and this is template
    expansion. If that is wrong, tell me before I start.

  2. tonygermano commented on Oct 29, 2026

    @tonygermano
    Member

    I don't quite understand what your proposed solution is, but we don't want to break velocity. You can actually read a key with dots in a similar manner to javascript using the maps variable placed in the velocity context like ${maps.get('db.warehouse.url')}.

  3. djkene70 commented on Oct 29, 2026

    @djkene70
    Author

    You are right, and thank you — ${maps.get('db.warehouse.url')} does work. I went and
    checked rather than take my own word for it: ValueReplacer.getDefaultContext() puts
    maps into the context as a MapTool, loadContextFromMap() adds every loaded map to
    that tool, and the Configuration Map is one of them, so a dotted key is reachable today.

    So let me withdraw the part you were reacting to. I am not proposing to change how
    Velocity resolves ${a.b.c}, and I agree that would be the wrong trade.

    What I would still like to ask about is the other half of the report, which the workaround
    does not change: when a reference cannot be resolved, nothing says so. The literal
    ${...} is handed to the connector and the failure surfaces as
    No suitable driver found for ${test.cfgmap.url}, which points at the connector rather
    than at the key. maps.get() on a missing key returns null and renders the same way, so
    that is true for both spellings.

    Would either of these be welcome, or would you rather I just close this?

    1. Documentation only — say plainly that Configuration Map keys containing dots need
      ${maps.get('key')}.
    2. A log warning when a resolved template still contains an unresolved ${...}. No
      behaviour change, no new syntax.

    Happy to take whichever you prefer, or none.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions