debezium / debezium/dbz

Oracle Hybrid Strategy is not compatible with column filtering

Open
#1,599 8 comments 0 reactions 1 assignee Claimed by @div-dev123 View on GitHub
component/oracle-connector type/bug
Dominant language
HTML
Stars
6
Forks
8
Avg merge
2d 19h
Merged PRs (30d)
1

Description

## Bug report

When setting `column.include.list` or `column.exclude.list`, the relational `Table` model is constructed with only the columns that match the given filter. However, when a column is omitted, and the Oracle Hybrid strategy attempts to resolve a column ordinal to a name, this fails if that given column is omitted.

```
2026-02-08T21:13:22,092 ERROR Oracle||streaming Oracle LogMiner is unable to re-construct the SQL for 'UPDATE' event with SCN 6559312557893 [io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource]
2026-02-08T21:13:22,092 ERROR Oracle||streaming LogMiner session stopped due to an error. [io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource]
io.debezium.connector.oracle.logminer.parser.DmlParserException: DML statement couldn't be parsed. Please open a Jira issue with the statement 'update "WMS"."TBL_SH_ROUTES_POINTS" set "COL 2" = HEXTORAW('c50303174c07'), "COL 3" = HEXTORAW('c503011e1911'), "COL 4" = HEXTORAW('c503010f325d'), "COL 5" = HEXTORAW('787e02080a3019'), "COL 6" = HEXTORAW('787e0208162c1b'), "COL 7" = HEXTORAW('787e0208183108'), "COL 8" = NULL, "COL 9" = HEXTORAW('30'), "COL 10" = HEXTORAW('c10333'), "COL 11" = HEXTORAW('c10333'), "COL 12" = HEXTORAW('c10c'), "COL 13" = HEXTORAW('c3031217'), "COL 14" = NULL, "COL 15" = HEXTORAW('534d49524e4f5641'), "COL 16" = HEXTORAW('787e0209010125'), "COL 17" = NULL, "COL 18" = NULL, "COL 19" = HEXTORAW('80'), "COL 20" = HEXTORAW('c10333'), "COL 21" = HEXTORAW('c503010f3925'), "COL 22" = HEXTORAW('80'), "COL 23" = NULL, "COL 24" = HEXTORAW('53'), "COL 25" = HEXTORAW('4132394432303133303736383338353945303533453030343035304136364339'), "COL 26" = HEXTORAW('c106'), "COL 27" = HEXTORAW('c106'), "COL 28" = HEXTORAW('01'), "COL 29" = HEXTORAW('7064') where "COL 1" = HEXTORAW('c50308310c1b') and "COL 2" = HEXTORAW('c50303174c07') and "COL 3" = HEXTORAW('c503011e1911') and "COL 4" = HEXTORAW('c503010f325d') and "COL 5" = HEXTORAW('787e02080a3019') and "COL 6" = HEXTORAW('787e0208162c1b') and "COL 7" = HEXTORAW('787e0208183108') and "COL 8" IS NULL and "COL 9" = HEXTORAW('30') and "COL 10" = HEXTORAW('c10333') and "COL 11" = HEXTORAW('c103') and "COL 12" = HEXTORAW('c10c') and "COL 13" = HEXTORAW('c3031217') and "COL 14" IS NULL and "COL 15" = HEXTORAW('534d49524e4f5641') and "COL 16" = HEXTORAW('787e020818361b') and "COL 17" IS NULL and "COL 18" IS NULL and "COL 19" = HEXTORAW('80') and "COL 20" = HEXTORAW('c10333') and "COL 21" = HEXTORAW('c503010f3925') and "COL 22" = HEXTORAW('80') and "COL 23" IS NULL and "COL 24" = HEXTORAW('53') and "COL 25" = HEXTORAW('4132394432303133303736383338353945303533453030343035304136364339') and "COL 26" = HEXTORAW('c106') and "COL 27" = HEXTORAW('c106') and "COL 28" = HEXTORAW('01') and "COL 29" = HEXTORAW('7064');'.
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.parseDmlStatement(AbstractLogMinerStreamingChangeEventSource.java:1451) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.dispatchDataChangeEventInternal(AbstractLogMinerStreamingChangeEventSource.java:1313) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.handleDataChangeEvent(AbstractLogMinerStreamingChangeEventSource.java:615) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.processEvent(AbstractLogMinerStreamingChangeEventSource.java:481) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.executeAndProcessQuery(AbstractLogMinerStreamingChangeEventSource.java:404) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.buffered.BufferedLogMinerStreamingChangeEventSource.process(BufferedLogMinerStreamingChangeEventSource.java:243) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.buffered.BufferedLogMinerStreamingChangeEventSource.executeLogMiningStreaming(BufferedLogMinerStreamingChangeEventSource.java:156) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.execute(AbstractLogMinerStreamingChangeEventSource.java:212) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.execute(AbstractLogMinerStreamingChangeEventSource.java:88) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.pipeline.ChangeEventSourceCoordinator.streamEvents(ChangeEventSourceCoordinator.java:329) ~[debezium-core-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.pipeline.ChangeEventSourceCoordinator.executeChangeEventSources(ChangeEventSourceCoordinator.java:207) ~[debezium-core-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.pipeline.ChangeEventSourceCoordinator.lambda$start$0(ChangeEventSourceCoordinator.java:147) ~[debezium-core-3.3.1.Final.jar:3.3.1.Final]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) ~[?:?]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?]
at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
Caused by: io.debezium.connector.oracle.logminer.parser.DmlParserException: Failed to parse update DML: 'update "WMS"."TBL_SH_ROUTES_POINTS" set "COL 2" = HEXTORAW('c50303174c07'), "COL 3" = HEXTORAW('c503011e1911'), "COL 4" = HEXTORAW('c503010f325d'), "COL 5" = HEXTORAW('787e02080a3019'), "COL 6" = HEXTORAW('787e0208162c1b'), "COL 7" = HEXTORAW('787e0208183108'), "COL 8" = NULL, "COL 9" = HEXTORAW('30'), "COL 10" = HEXTORAW('c10333'), "COL 11" = HEXTORAW('c10333'), "COL 12" = HEXTORAW('c10c'), "COL 13" = HEXTORAW('c3031217'), "COL 14" = NULL, "COL 15" = HEXTORAW('534d49524e4f5641'), "COL 16" = HEXTORAW('787e0209010125'), "COL 17" = NULL, "COL 18" = NULL, "COL 19" = HEXTORAW('80'), "COL 20" = HEXTORAW('c10333'), "COL 21" = HEXTORAW('c503010f3925'), "COL 22" = HEXTORAW('80'), "COL 23" = NULL, "COL 24" = HEXTORAW('53'), "COL 25" = HEXTORAW('4132394432303133303736383338353945303533453030343035304136364339'), "COL 26" = HEXTORAW('c106'), "COL 27" = HEXTORAW('c106'), "COL 28" = HEXTORAW('01'), "COL 29" = HEXTORAW('7064') where "COL 1" = HEXTORAW('c50308310c1b') and "COL 2" = HEXTORAW('c50303174c07') and "COL 3" = HEXTORAW('c503011e1911') and "COL 4" = HEXTORAW('c503010f325d') and "COL 5" = HEXTORAW('787e02080a3019') and "COL 6" = HEXTORAW('787e0208162c1b') and "COL 7" = HEXTORAW('787e0208183108') and "COL 8" IS NULL and "COL 9" = HEXTORAW('30') and "COL 10" = HEXTORAW('c10333') and "COL 11" = HEXTORAW('c103') and "COL 12" = HEXTORAW('c10c') and "COL 13" = HEXTORAW('c3031217') and "COL 14" IS NULL and "COL 15" = HEXTORAW('534d49524e4f5641') and "COL 16" = HEXTORAW('787e020818361b') and "COL 17" IS NULL and "COL 18" IS NULL and "COL 19" = HEXTORAW('80') and "COL 20" = HEXTORAW('c10333') and "COL 21" = HEXTORAW('c503010f3925') and "COL 22" = HEXTORAW('80') and "COL 23" IS NULL and "COL 24" = HEXTORAW('53') and "COL 25" = HEXTORAW('4132394432303133303736383338353945303533453030343035304136364339') and "COL 26" = HEXTORAW('c106') and "COL 27" = HEXTORAW('c106') and "COL 28" = HEXTORAW('01') and "COL 29" = HEXTORAW('7064');'
at io.debezium.connector.oracle.logminer.parser.LogMinerDmlParser.parseUpdate(LogMinerDmlParser.java:173) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.parser.LogMinerDmlParser.parse(LogMinerDmlParser.java:82) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.parseDmlStatement(AbstractLogMinerStreamingChangeEventSource.java:1432) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
... 16 more
Caused by: io.debezium.DebeziumException: Failed to find column COL 29 in table column position cache
at io.debezium.connector.oracle.logminer.parser.LogMinerColumnResolverDmlParser.getColumnIndexByName(LogMinerColumnResolverDmlParser.java:45) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.parser.LogMinerDmlParser.parseSetClause(LogMinerDmlParser.java:526) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.parser.LogMinerDmlParser.parseUpdate(LogMinerDmlParser.java:148) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.parser.LogMinerDmlParser.parse(LogMinerDmlParser.java:82) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.parseDmlStatement(AbstractLogMinerStreamingChangeEventSource.java:1432) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
... 16 more
2026-02-08T21:13:22,093 ERROR Oracle||streaming Producer failure [io.debezium.pipeline.ErrorHandler]
io.debezium.connector.oracle.logminer.parser.DmlParserException: DML statement couldn't be parsed. Please open a Jira issue with the statement 'update "WMS"."TBL_SH_ROUTES_POINTS" set "COL 2" = HEXTORAW('c50303174c07'), "COL 3" = HEXTORAW('c503011e1911'), "COL 4" = HEXTORAW('c503010f325d'), "COL 5" = HEXTORAW('787e02080a3019'), "COL 6" = HEXTORAW('787e0208162c1b'), "COL 7" = HEXTORAW('787e0208183108'), "COL 8" = NULL, "COL 9" = HEXTORAW('30'), "COL 10" = HEXTORAW('c10333'), "COL 11" = HEXTORAW('c10333'), "COL 12" = HEXTORAW('c10c'), "COL 13" = HEXTORAW('c3031217'), "COL 14" = NULL, "COL 15" = HEXTORAW('534d49524e4f5641'), "COL 16" = HEXTORAW('787e0209010125'), "COL 17" = NULL, "COL 18" = NULL, "COL 19" = HEXTORAW('80'), "COL 20" = HEXTORAW('c10333'), "COL 21" = HEXTORAW('c503010f3925'), "COL 22" = HEXTORAW('80'), "COL 23" = NULL, "COL 24" = HEXTORAW('53'), "COL 25" = HEXTORAW('4132394432303133303736383338353945303533453030343035304136364339'), "COL 26" = HEXTORAW('c106'), "COL 27" = HEXTORAW('c106'), "COL 28" = HEXTORAW('01'), "COL 29" = HEXTORAW('7064') where "COL 1" = HEXTORAW('c50308310c1b') and "COL 2" = HEXTORAW('c50303174c07') and "COL 3" = HEXTORAW('c503011e1911') and "COL 4" = HEXTORAW('c503010f325d') and "COL 5" = HEXTORAW('787e02080a3019') and "COL 6" = HEXTORAW('787e0208162c1b') and "COL 7" = HEXTORAW('787e0208183108') and "COL 8" IS NULL and "COL 9" = HEXTORAW('30') and "COL 10" = HEXTORAW('c10333') and "COL 11" = HEXTORAW('c103') and "COL 12" = HEXTORAW('c10c') and "COL 13" = HEXTORAW('c3031217') and "COL 14" IS NULL and "COL 15" = HEXTORAW('534d49524e4f5641') and "COL 16" = HEXTORAW('787e020818361b') and "COL 17" IS NULL and "COL 18" IS NULL and "COL 19" = HEXTORAW('80') and "COL 20" = HEXTORAW('c10333') and "COL 21" = HEXTORAW('c503010f3925') and "COL 22" = HEXTORAW('80') and "COL 23" IS NULL and "COL 24" = HEXTORAW('53') and "COL 25" = HEXTORAW('4132394432303133303736383338353945303533453030343035304136364339') and "COL 26" = HEXTORAW('c106') and "COL 27" = HEXTORAW('c106') and "COL 28" = HEXTORAW('01') and "COL 29" = HEXTORAW('7064');'.
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.parseDmlStatement(AbstractLogMinerStreamingChangeEventSource.java:1451) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.dispatchDataChangeEventInternal(AbstractLogMinerStreamingChangeEventSource.java:1313) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.handleDataChangeEvent(AbstractLogMinerStreamingChangeEventSource.java:615) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.processEvent(AbstractLogMinerStreamingChangeEventSource.java:481) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.executeAndProcessQuery(AbstractLogMinerStreamingChangeEventSource.java:404) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.buffered.BufferedLogMinerStreamingChangeEventSource.process(BufferedLogMinerStreamingChangeEventSource.java:243) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.buffered.BufferedLogMinerStreamingChangeEventSource.executeLogMiningStreaming(BufferedLogMinerStreamingChangeEventSource.java:156) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.execute(AbstractLogMinerStreamingChangeEventSource.java:212) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.execute(AbstractLogMinerStreamingChangeEventSource.java:88) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.pipeline.ChangeEventSourceCoordinator.streamEvents(ChangeEventSourceCoordinator.java:329) ~[debezium-core-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.pipeline.ChangeEventSourceCoordinator.executeChangeEventSources(ChangeEventSourceCoordinator.java:207) ~[debezium-core-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.pipeline.ChangeEventSourceCoordinator.lambda$start$0(ChangeEventSourceCoordinator.java:147) ~[debezium-core-3.3.1.Final.jar:3.3.1.Final]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) ~[?:?]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?]
at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
Caused by: io.debezium.connector.oracle.logminer.parser.DmlParserException: Failed to parse update DML: 'update "WMS"."TBL_SH_ROUTES_POINTS" set "COL 2" = HEXTORAW('c50303174c07'), "COL 3" = HEXTORAW('c503011e1911'), "COL 4" = HEXTORAW('c503010f325d'), "COL 5" = HEXTORAW('787e02080a3019'), "COL 6" = HEXTORAW('787e0208162c1b'), "COL 7" = HEXTORAW('787e0208183108'), "COL 8" = NULL, "COL 9" = HEXTORAW('30'), "COL 10" = HEXTORAW('c10333'), "COL 11" = HEXTORAW('c10333'), "COL 12" = HEXTORAW('c10c'), "COL 13" = HEXTORAW('c3031217'), "COL 14" = NULL, "COL 15" = HEXTORAW('534d49524e4f5641'), "COL 16" = HEXTORAW('787e0209010125'), "COL 17" = NULL, "COL 18" = NULL, "COL 19" = HEXTORAW('80'), "COL 20" = HEXTORAW('c10333'), "COL 21" = HEXTORAW('c503010f3925'), "COL 22" = HEXTORAW('80'), "COL 23" = NULL, "COL 24" = HEXTORAW('53'), "COL 25" = HEXTORAW('4132394432303133303736383338353945303533453030343035304136364339'), "COL 26" = HEXTORAW('c106'), "COL 27" = HEXTORAW('c106'), "COL 28" = HEXTORAW('01'), "COL 29" = HEXTORAW('7064') where "COL 1" = HEXTORAW('c50308310c1b') and "COL 2" = HEXTORAW('c50303174c07') and "COL 3" = HEXTORAW('c503011e1911') and "COL 4" = HEXTORAW('c503010f325d') and "COL 5" = HEXTORAW('787e02080a3019') and "COL 6" = HEXTORAW('787e0208162c1b') and "COL 7" = HEXTORAW('787e0208183108') and "COL 8" IS NULL and "COL 9" = HEXTORAW('30') and "COL 10" = HEXTORAW('c10333') and "COL 11" = HEXTORAW('c103') and "COL 12" = HEXTORAW('c10c') and "COL 13" = HEXTORAW('c3031217') and "COL 14" IS NULL and "COL 15" = HEXTORAW('534d49524e4f5641') and "COL 16" = HEXTORAW('787e020818361b') and "COL 17" IS NULL and "COL 18" IS NULL and "COL 19" = HEXTORAW('80') and "COL 20" = HEXTORAW('c10333') and "COL 21" = HEXTORAW('c503010f3925') and "COL 22" = HEXTORAW('80') and "COL 23" IS NULL and "COL 24" = HEXTORAW('53') and "COL 25" = HEXTORAW('4132394432303133303736383338353945303533453030343035304136364339') and "COL 26" = HEXTORAW('c106') and "COL 27" = HEXTORAW('c106') and "COL 28" = HEXTORAW('01') and "COL 29" = HEXTORAW('7064');'
at io.debezium.connector.oracle.logminer.parser.LogMinerDmlParser.parseUpdate(LogMinerDmlParser.java:173) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.parser.LogMinerDmlParser.parse(LogMinerDmlParser.java:82) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.parseDmlStatement(AbstractLogMinerStreamingChangeEventSource.java:1432) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
... 16 more
Caused by: io.debezium.DebeziumException: Failed to find column COL 29 in table column position cache
at io.debezium.connector.oracle.logminer.parser.LogMinerColumnResolverDmlParser.getColumnIndexByName(LogMinerColumnResolverDmlParser.java:45) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.parser.LogMinerDmlParser.parseSetClause(LogMinerDmlParser.java:526) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.parser.LogMinerDmlParser.parseUpdate(LogMinerDmlParser.java:148) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.parser.LogMinerDmlParser.parse(LogMinerDmlParser.java:82) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
at io.debezium.connector.oracle.logminer.AbstractLogMinerStreamingChangeEventSource.parseDmlStatement(AbstractLogMinerStreamingChangeEventSource.java:1432) ~[debezium-connector-oracle-3.3.1.Final.jar:3.3.1.Final]
... 16 more
```

## Workaround

The current workaround is to move column filtering into a transformation, so that the relational model retains all columns and works as expected with the `hybrid` mining strategy.

## Implementation Ideas

There are two possible ideas to address the shortcomings.

1. In the Oracle connector, identify if a column with the specified _ordinal_ is defined. If it isn't defined, we should omit handling of that column in the SQL parsing. This keeps the logic centralized in the Oracle connector; however, it will be highly dependent on being able to properly map columns by ordinal when columns are missing. This will need to be tested.
2. We instead rethink what the `Table` model represents, and we move the complex logic of omitting columns to the `TableSchemaBuilder` where we build the schema and value mappers. This would allow the `Table` to hold any number of columns, including virtual or hidden columns, despite them being ignored and not part of the event. But this is a much larger sweeping change that makes more sense for a major update than in a minor update.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.